xref: /netbsd-src/external/mpl/bind/dist/bin/tests/system/digdelv/tests.sh (revision dd3ee07da436799d8de85f3055253118b76bf345)
1#!/bin/sh
2#
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# This Source Code Form is subject to the terms of the Mozilla Public
6# License, v. 2.0. If a copy of the MPL was not distributed with this
7# file, you can obtain one at https://mozilla.org/MPL/2.0/.
8#
9# See the COPYRIGHT file distributed with this work for additional
10# information regarding copyright ownership.
11
12# shellcheck source=conf.sh
13SYSTEMTESTTOP=..
14. "$SYSTEMTESTTOP/conf.sh"
15
16set -e
17
18status=0
19n=0
20
21sendcmd() {
22    "$PERL" "$SYSTEMTESTTOP/send.pl" "${1}" "$EXTRAPORT1"
23}
24
25dig_with_opts() {
26    "$DIG" -p "$PORT" "$@"
27}
28
29mdig_with_opts() {
30    "$MDIG" -p "$PORT" "$@"
31}
32
33# Check if response in file $1 has the correct TTL range.
34# The response record must have RRtype $2 and class IN (CLASS1).
35# Maximum TTL is given by $3.  This works in most cases where TTL is
36# the second word on the line.  TTL position can be adjusted with
37# setting the position $4, but that requires updating this function.
38check_ttl_range() {
39    file=$1
40    pos=$4
41
42    case "$pos" in
43    "3")
44    awk -v rrtype="$2" -v ttl="$3" '($4 == "IN" || $4 == "CLASS1" ) && $5 == rrtype { if ($3 <= ttl) { ok=1 } } END { exit(ok?0:1) }' < $file
45    ;;
46    *)
47    awk -v rrtype="$2" -v ttl="$3" '($3 == "IN" || $3 == "CLASS1" ) && $4 == rrtype { if ($2 <= ttl) { ok=1 } } END { exit(ok?0:1) }' < $file
48    ;;
49    esac
50
51   result=$?
52   [ $result -eq 0 ] || echo_i "ttl check failed"
53   return $result
54}
55
56# using delv insecure mode as not testing dnssec here
57delv_with_opts() {
58    "$DELV" +noroot -p "$PORT" "$@"
59}
60
61KEYID="$(cat ns2/keyid)"
62KEYDATA="$(< ns2/keydata sed -e 's/+/[+]/g')"
63NOSPLIT="$(< ns2/keydata sed -e 's/+/[+]/g' -e 's/ //g')"
64
65HAS_PYYAML=0
66if [ -n "$PYTHON" ] ; then
67	$PYTHON -c "import yaml" 2> /dev/null && HAS_PYYAML=1
68fi
69
70#
71# test whether ans7/ans.pl will be able to send a UPDATE response.
72# if it can't, we will log that below.
73#
74if "$PERL" -e 'use Net::DNS; use Net::DNS::Packet; my $p = new Net::DNS::Packet; $p->header->opcode(5);' > /dev/null 2>&1
75then
76	checkupdate=1
77else
78	checkupdate=0
79fi
80
81if [ -x "$NSLOOKUP" -a $checkupdate -eq 1 ] ; then
82
83  n=$((n+1))
84  echo_i "check nslookup handles UPDATE response ($n)"
85  ret=0
86  "$NSLOOKUP" -q=CNAME "-port=$PORT" foo.bar 10.53.0.7 > nslookup.out.test$n 2>&1 && ret=1
87  grep "Opcode mismatch" nslookup.out.test$n > /dev/null || ret=1
88  if [ $ret -ne 0 ]; then echo_i "failed"; fi
89  status=$((status+ret))
90
91fi
92
93if [ -x "$HOST" -a $checkupdate -eq 1 ] ; then
94
95  n=$((n+1))
96  echo_i "check host handles UPDATE response ($n)"
97  ret=0
98  "$HOST" -t CNAME -p $PORT foo.bar 10.53.0.7 > host.out.test$n 2>&1 && ret=1
99  grep "Opcode mismatch" host.out.test$n > /dev/null || ret=1
100  if [ $ret -ne 0 ]; then echo_i "failed"; fi
101  status=$((status+ret))
102
103fi
104
105if [ -x "$NSUPDATE" -a $checkupdate -eq 1 ] ; then
106
107  n=$((n+1))
108  echo_i "check nsupdate handles UPDATE response to QUERY ($n)"
109  ret=0
110  res=0
111  $NSUPDATE << EOF > nsupdate.out.test$n 2>&1 || res=$?
112server 10.53.0.7 ${PORT}
113add x.example.com 300 in a 1.2.3.4
114send
115EOF
116  test $res -eq 1 || ret=1
117  grep "invalid OPCODE in response to SOA query" nsupdate.out.test$n > /dev/null || ret=1
118  if [ $ret -ne 0 ]; then echo_i "failed"; fi
119  status=$((status+ret))
120
121fi
122
123if [ -x "$DIG" ] ; then
124
125  if [ $checkupdate -eq 1 ] ; then
126
127    n=$((n+1))
128    echo_i "check dig handles UPDATE response ($n)"
129    ret=0
130    dig_with_opts @10.53.0.7 cname foo.bar > dig.out.test$n 2>&1 && ret=1
131    grep "Opcode mismatch" dig.out.test$n > /dev/null || ret=1
132    if [ $ret -ne 0 ]; then echo_i "failed"; fi
133    status=$((status+ret))
134  else
135    echo_i "Skipped UPDATE handling test"
136  fi
137
138  n=$((n+1))
139  echo_i "checking dig short form works ($n)"
140  ret=0
141  dig_with_opts @10.53.0.3 +short a a.example > dig.out.test$n || ret=1
142  test "$(wc -l < dig.out.test$n)" -eq 1 || ret=1
143  if [ $ret -ne 0 ]; then echo_i "failed"; fi
144  status=$((status+ret))
145
146  n=$((n+1))
147  echo_i "checking dig split width works ($n)"
148  ret=0
149  dig_with_opts @10.53.0.3 +split=4 -t sshfp foo.example > dig.out.test$n || ret=1
150  grep " 9ABC DEF6 7890 " < dig.out.test$n > /dev/null || ret=1
151  check_ttl_range dig.out.test$n "SSHFP" 300 || ret=1
152  if [ $ret -ne 0 ]; then echo_i "failed"; fi
153  status=$((status+ret))
154
155  n=$((n+1))
156  echo_i "checking dig +unknownformat works ($n)"
157  ret=0
158  dig_with_opts @10.53.0.3 +unknownformat a a.example > dig.out.test$n || ret=1
159  grep "CLASS1[ 	][ 	]*TYPE1[ 	][ 	]*\\\\# 4 0A000001" < dig.out.test$n > /dev/null || ret=1
160  check_ttl_range dig.out.test$n "TYPE1" 300 || ret=1
161  if [ $ret -ne 0 ]; then echo_i "failed"; fi
162  status=$((status+ret))
163
164  n=$((n+1))
165  echo_i "checking dig with reverse lookup works ($n)"
166  ret=0
167  dig_with_opts @10.53.0.3 -x 127.0.0.1 > dig.out.test$n 2>&1 || ret=1
168  # doesn't matter if has answer
169  grep -i "127\\.in-addr\\.arpa\\." < dig.out.test$n > /dev/null || ret=1
170  check_ttl_range dig.out.test$n "SOA" 86400 || ret=1
171  if [ $ret -ne 0 ]; then echo_i "failed"; fi
172  status=$((status+ret))
173
174  n=$((n+1))
175  echo_i "checking dig over TCP works ($n)"
176  ret=0
177  dig_with_opts +tcp @10.53.0.3 a a.example > dig.out.test$n || ret=1
178  grep "10\\.0\\.0\\.1$" < dig.out.test$n > /dev/null || ret=1
179  check_ttl_range dig.out.test$n "A" 300 || ret=1
180  if [ $ret -ne 0 ]; then echo_i "failed"; fi
181  status=$((status+ret))
182
183  n=$((n+1))
184  echo_i "checking dig +multi +norrcomments works for DNSKEY (when default is rrcomments)($n)"
185  ret=0
186  dig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t DNSKEY example > dig.out.test$n || ret=1
187  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" dig.out.test$n > /dev/null && ret=1
188  check_ttl_range dig.out.test$n "DNSKEY" 300 || ret=1
189  if [ $ret -ne 0 ]; then echo_i "failed"; fi
190  status=$((status+ret))
191
192  n=$((n+1))
193  echo_i "checking dig +multi +norrcomments works for SOA (when default is rrcomments)($n)"
194  ret=0
195  dig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t SOA example > dig.out.test$n || ret=1
196  grep "; serial" dig.out.test$n > /dev/null && ret=1
197  check_ttl_range dig.out.test$n "SOA" 300 || ret=1
198  if [ $ret -ne 0 ]; then echo_i "failed"; fi
199  status=$((status+ret))
200
201  n=$((n+1))
202  echo_i "checking dig +rrcomments works for DNSKEY($n)"
203  ret=0
204  dig_with_opts +tcp @10.53.0.3 +rrcomments DNSKEY example > dig.out.test$n || ret=1
205  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" < dig.out.test$n > /dev/null || ret=1
206  check_ttl_range dig.out.test$n "DNSKEY" 300 || ret=1
207  if [ $ret -ne 0 ]; then echo_i "failed"; fi
208  status=$((status+ret))
209
210  n=$((n+1))
211  echo_i "checking dig +short +rrcomments works for DNSKEY ($n)"
212  ret=0
213  dig_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example > dig.out.test$n || ret=1
214  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" < dig.out.test$n > /dev/null || ret=1
215  if [ $ret -ne 0 ]; then echo_i "failed"; fi
216  status=$((status+ret))
217
218  n=$((n+1))
219  echo_i "checking dig +short +nosplit works($n)"
220  ret=0
221  dig_with_opts +tcp @10.53.0.3 +short +nosplit DNSKEY example > dig.out.test$n || ret=1
222  grep "$NOSPLIT" < dig.out.test$n > /dev/null || ret=1
223  if [ $ret -ne 0 ]; then echo_i "failed"; fi
224  status=$((status+ret))
225
226  n=$((n+1))
227  echo_i "checking dig +short +rrcomments works($n)"
228  ret=0
229  dig_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example > dig.out.test$n || ret=1
230  grep -q "$KEYDATA  ; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID\$" < dig.out.test$n || ret=1
231  if [ $ret -ne 0 ]; then echo_i "failed"; fi
232  status=$((status+ret))
233
234  n=$((n+1))
235  echo_i "checking dig multi flag is local($n)"
236  ret=0
237  dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +nomulti example +nomulti > dig.out.nn.$n || ret=1
238  dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +multi example +nomulti > dig.out.mn.$n || ret=1
239  dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +nomulti example +multi > dig.out.nm.$n || ret=1
240  dig_with_opts +tcp @10.53.0.3 -t DNSKEY example +multi example +multi > dig.out.mm.$n || ret=1
241  lcnn=$(wc -l < dig.out.nn.$n)
242  lcmn=$(wc -l < dig.out.mn.$n)
243  lcnm=$(wc -l < dig.out.nm.$n)
244  lcmm=$(wc -l < dig.out.mm.$n)
245  test "$lcmm" -ge "$lcnm" || ret=1
246  test "$lcmm" -ge "$lcmn" || ret=1
247  test "$lcnm" -ge "$lcnn" || ret=1
248  test "$lcmn" -ge "$lcnn" || ret=1
249  check_ttl_range dig.out.nn.$n "DNSKEY" 300 || ret=1
250  check_ttl_range dig.out.mn.$n "DNSKEY" 300 || ret=1
251  check_ttl_range dig.out.nm.$n "DNSKEY" 300 || ret=1
252  check_ttl_range dig.out.mm.$n "DNSKEY" 300 || ret=1
253  if [ $ret -ne 0 ]; then echo_i "failed"; fi
254  status=$((status+ret))
255
256  n=$((n+1))
257  echo_i "checking dig +noheader-only works ($n)"
258  ret=0
259  dig_with_opts +tcp @10.53.0.3 +noheader-only A example > dig.out.test$n || ret=1
260  grep "Got answer:" < dig.out.test$n > /dev/null || ret=1
261  check_ttl_range dig.out.test$n "SOA" 300 || ret=1
262  if [ $ret -ne 0 ]; then echo_i "failed"; fi
263  status=$((status+ret))
264
265  n=$((n+1))
266  echo_i "checking dig +short +rrcomments works($n)"
267  ret=0
268  dig_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example > dig.out.test$n || ret=1
269  grep -q "$KEYDATA  ; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID\$" < dig.out.test$n || ret=1
270  if [ $ret -ne 0 ]; then echo_i "failed"; fi
271  status=$((status+ret))
272
273  n=$((n+1))
274  echo_i "checking dig +header-only works ($n)"
275  ret=0
276  dig_with_opts +tcp @10.53.0.3 +header-only example > dig.out.test$n || ret=1
277  grep "^;; flags: qr rd; QUERY: 0, ANSWER: 0," < dig.out.test$n > /dev/null || ret=1
278  grep "^;; QUESTION SECTION:" < dig.out.test$n > /dev/null && ret=1
279  if [ $ret -ne 0 ]; then echo_i "failed"; fi
280  status=$((status+ret))
281
282  n=$((n+1))
283  echo_i "checking dig +raflag works ($n)"
284  ret=0
285  dig_with_opts +tcp @10.53.0.3 +raflag +qr example > dig.out.test$n || ret=1
286  grep "^;; flags: rd ra ad; QUERY: 1, ANSWER: 0," < dig.out.test$n > /dev/null || ret=1
287  grep "^;; flags: qr rd ra; QUERY: 1, ANSWER: 0," < dig.out.test$n > /dev/null || ret=1
288  check_ttl_range dig.out.test$n "SOA" 300 || ret=1
289  if [ $ret -ne 0 ]; then echo_i "failed"; fi
290  status=$((status+ret))
291
292  n=$((n+1))
293  echo_i "checking dig +tcflag works ($n)"
294  ret=0
295  dig_with_opts +tcp @10.53.0.3 +tcflag +qr example > dig.out.test$n || ret=1
296  grep "^;; flags: tc rd ad; QUERY: 1, ANSWER: 0" < dig.out.test$n > /dev/null || ret=1
297  grep "^;; flags: qr rd ra; QUERY: 1, ANSWER: 0," < dig.out.test$n > /dev/null || ret=1
298  check_ttl_range dig.out.test$n "SOA" 300 || ret=1
299  if [ $ret -ne 0 ]; then echo_i "failed"; fi
300  status=$((status+ret))
301
302  n=$((n+1))
303  echo_i "checking dig +header-only works (with class and type set) ($n)"
304  ret=0
305  dig_with_opts +tcp @10.53.0.3 +header-only -c IN -t A example > dig.out.test$n || ret=1
306  grep "^;; flags: qr rd; QUERY: 0, ANSWER: 0," < dig.out.test$n > /dev/null || ret=1
307  grep "^;; QUESTION SECTION:" < dig.out.test$n > /dev/null && ret=1
308  if [ $ret -ne 0 ]; then echo_i "failed"; fi
309  status=$((status+ret))
310
311  n=$((n+1))
312  echo_i "checking dig +zflag works, and that BIND properly ignores it ($n)"
313  ret=0
314  dig_with_opts +tcp @10.53.0.3 +zflag +qr A example > dig.out.test$n || ret=1
315  sed -n '/Sending:/,/Got answer:/p' dig.out.test$n | grep "^;; flags: rd ad; MBZ: 0x4;" > /dev/null || ret=1
316  sed -n '/Got answer:/,/AUTHORITY SECTION:/p' dig.out.test$n | grep "^;; flags: qr rd ra; QUERY: 1" > /dev/null || ret=1
317  check_ttl_range dig.out.test$n "SOA" 300 || ret=1
318  if [ $ret -ne 0 ]; then echo_i "failed"; fi
319  status=$((status+ret))
320
321  n=$((n+1))
322  echo_i "checking dig +qr +ednsopt=08 does not cause an INSIST failure ($n)"
323  ret=0
324  dig_with_opts @10.53.0.3 +ednsopt=08 +qr a a.example > dig.out.test$n || ret=1
325  grep "INSIST" < dig.out.test$n > /dev/null && ret=1
326  grep "FORMERR" < dig.out.test$n > /dev/null || ret=1
327  if [ $ret -ne 0 ]; then echo_i "failed"; fi
328  status=$((status+ret))
329
330  n=$((n+1))
331  echo_i "checking dig +ttlunits works ($n)"
332  ret=0
333  dig_with_opts +tcp @10.53.0.2 +ttlunits A weeks.example > dig.out.test$n || ret=1
334  grep "^weeks.example.		3w" < dig.out.test$n > /dev/null || ret=1
335  dig_with_opts +tcp @10.53.0.2 +ttlunits A days.example > dig.out.test$n || ret=1
336  grep "^days.example.		3d" < dig.out.test$n > /dev/null || ret=1
337  dig_with_opts +tcp @10.53.0.2 +ttlunits A hours.example > dig.out.test$n || ret=1
338  grep "^hours.example.		3h" < dig.out.test$n > /dev/null || ret=1
339  dig_with_opts +tcp @10.53.0.2 +ttlunits A minutes.example > dig.out.test$n || ret=1
340  grep "^minutes.example.	45m" < dig.out.test$n > /dev/null || ret=1
341  dig_with_opts +tcp @10.53.0.2 +ttlunits A seconds.example > dig.out.test$n || ret=1
342  grep "^seconds.example.	45s" < dig.out.test$n > /dev/null || ret=1
343  if [ $ret -ne 0 ]; then echo_i "failed"; fi
344  status=$((status+ret))
345
346  n=$((n+1))
347  echo_i "checking dig respects precedence of options with +ttlunits ($n)"
348  ret=0
349  dig_with_opts +tcp @10.53.0.2 +ttlunits +nottlid A weeks.example > dig.out.test$n || ret=1
350  grep "^weeks.example.		IN" < dig.out.test$n > /dev/null || ret=1
351  dig_with_opts +tcp @10.53.0.2 +nottlid +ttlunits A weeks.example > dig.out.test$n || ret=1
352  grep "^weeks.example.		3w" < dig.out.test$n > /dev/null || ret=1
353  dig_with_opts +tcp @10.53.0.2 +nottlid +nottlunits A weeks.example > dig.out.test$n || ret=1
354  grep "^weeks.example.		1814400" < dig.out.test$n > /dev/null || ret=1
355  if [ $ret -ne 0 ]; then echo_i "failed"; fi
356  status=$((status+ret))
357
358  n=$((n+1))
359  echo_i "checking dig preserves origin on TCP retries ($n)"
360  ret=0
361  # Ask ans4 to still accept TCP connections, but not respond to queries
362  echo "//" | sendcmd 10.53.0.4
363  dig_with_opts -d +tcp @10.53.0.4 +retry=1 +time=1 +domain=bar foo > dig.out.test$n 2>&1 && ret=1
364  test "$(grep -c "trying origin bar" dig.out.test$n)" -eq 2 || ret=1
365  grep "using root origin" < dig.out.test$n > /dev/null && ret=1
366  if [ $ret -ne 0 ]; then echo_i "failed"; fi
367  status=$((status+ret))
368
369  n=$((n+1))
370  echo_i "checking dig -6 -4 ($n)"
371  ret=0
372  dig_with_opts +tcp @10.53.0.2 -4 -6 A a.example > dig.out.test$n 2>&1 && ret=1
373  grep "only one of -4 and -6 allowed" < dig.out.test$n > /dev/null || ret=1
374  if [ $ret -ne 0 ]; then echo_i "failed"; fi
375  status=$((status+ret))
376
377  n=$((n+1))
378  echo_i "checking dig @IPv6addr -4 A a.example ($n)"
379  if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null
380  then
381    ret=0
382    dig_with_opts +tcp @fd92:7065:b8e:ffff::2 -4 A a.example > dig.out.test$n 2>&1 && ret=1
383    grep "address family not supported" < dig.out.test$n > /dev/null || ret=1
384    if [ $ret -ne 0 ]; then echo_i "failed"; fi
385    status=$((status+ret))
386  else
387    echo_i "IPv6 unavailable; skipping"
388  fi
389
390  n=$((n+1))
391  echo_i "checking dig @IPv4addr -6 +mapped A a.example ($n)"
392  if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null && [ "$(uname -s)" != "OpenBSD" ]
393  then
394    ret=0
395    dig_with_opts +tcp @10.53.0.2 -6 +mapped A a.example > dig.out.test$n 2>&1 || ret=1
396    grep "SERVER: ::ffff:10.53.0.2#$PORT" < dig.out.test$n > /dev/null || ret=1
397    if [ $ret -ne 0 ]; then echo_i "failed"; fi
398    status=$((status+ret))
399  else
400    echo_i "IPv6 or IPv4-to-IPv6 mapping unavailable; skipping"
401  fi
402
403  n=$((n+1))
404  echo_i "checking dig +tcp @IPv4addr -6 +nomapped A a.example ($n)"
405  if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null
406  then
407    ret=0
408    dig_with_opts +tcp @10.53.0.2 -6 +nomapped A a.example > dig.out.test$n 2>&1 || ret=1
409    grep "SERVER: ::ffff:10.53.0.2#$PORT" < dig.out.test$n > /dev/null && ret=1
410    if [ $ret -ne 0 ]; then echo_i "failed"; fi
411    status=$((status+ret))
412  else
413    echo_i "IPv6 unavailable; skipping"
414  fi
415  n=$((n+1))
416
417  echo_i "checking dig +notcp @IPv4addr -6 +nomapped A a.example ($n)"
418  if testsock6 fd92:7065:b8e:ffff::2 2>/dev/null
419  then
420    ret=0
421    dig_with_opts +notcp @10.53.0.2 -6 +nomapped A a.example > dig.out.test$n 2>&1 || ret=1
422    grep "SERVER: ::ffff:10.53.0.2#$PORT" < dig.out.test$n > /dev/null && ret=1
423    if [ $ret -ne 0 ]; then echo_i "failed"; fi
424    status=$((status+ret))
425  else
426    echo_i "IPv6 unavailable; skipping"
427  fi
428
429  n=$((n+1))
430  echo_i "checking dig +subnet ($n)"
431  ret=0
432  dig_with_opts +tcp @10.53.0.2 +subnet=127.0.0.1 A a.example > dig.out.test$n 2>&1 || ret=1
433  grep "CLIENT-SUBNET: 127.0.0.1/32/0" < dig.out.test$n > /dev/null || ret=1
434  check_ttl_range dig.out.test$n "A" 300 || ret=1
435  if [ $ret -ne 0 ]; then echo_i "failed"; fi
436  status=$((status+ret))
437
438  n=$((n+1))
439  echo_i "checking dig +subnet +subnet ($n)"
440  ret=0
441  dig_with_opts +tcp @10.53.0.2 +subnet=127.0.0.0 +subnet=127.0.0.1 A a.example > dig.out.test$n 2>&1 || ret=1
442  grep "CLIENT-SUBNET: 127.0.0.1/32/0" < dig.out.test$n > /dev/null || ret=1
443  check_ttl_range dig.out.test$n "A" 300 || ret=1
444  if [ $ret -ne 0 ]; then echo_i "failed"; fi
445  status=$((status+ret))
446
447  n=$((n+1))
448  echo_i "checking dig +subnet with various prefix lengths ($n)"
449  ret=0
450  for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24; do
451      dig_with_opts +tcp @10.53.0.2 +subnet=255.255.255.255/$i A a.example > dig.out.$i.test$n 2>&1 || ret=1
452      case $i in
453      1|9|17) octet=128 ;;
454      2|10|18) octet=192 ;;
455      3|11|19) octet=224 ;;
456      4|12|20) octet=240 ;;
457      5|13|21) octet=248 ;;
458      6|14|22) octet=252 ;;
459      7|15|23) octet=254 ;;
460      8|16|24) octet=255 ;;
461      esac
462      case $i in
463      1|2|3|4|5|6|7|8) addr="${octet}.0.0.0";;
464      9|10|11|12|13|14|15|16) addr="255.${octet}.0.0";;
465      17|18|19|20|21|22|23|24) addr="255.255.${octet}.0" ;;
466      esac
467      grep "FORMERR" < dig.out.$i.test$n > /dev/null && ret=1
468      grep "CLIENT-SUBNET: $addr/$i/0" < dig.out.$i.test$n > /dev/null || ret=1
469      check_ttl_range dig.out.$i.test$n "A" 300 || ret=1
470  done
471  if [ $ret -ne 0 ]; then echo_i "failed"; fi
472  status=$((status+ret))
473
474  n=$((n+1))
475  echo_i "checking dig +subnet=0/0 ($n)"
476  ret=0
477  dig_with_opts +tcp @10.53.0.2 +subnet=0/0 A a.example > dig.out.test$n 2>&1 || ret=1
478  grep "status: NOERROR" < dig.out.test$n > /dev/null || ret=1
479  grep "CLIENT-SUBNET: 0.0.0.0/0/0" < dig.out.test$n > /dev/null || ret=1
480  grep "10.0.0.1" < dig.out.test$n > /dev/null || ret=1
481  check_ttl_range dig.out.test$n "A" 300 || ret=1
482  if [ $ret -ne 0 ]; then echo_i "failed"; fi
483  status=$((status+ret))
484
485  n=$((n+1))
486  echo_i "checking dig +subnet=0 ($n)"
487  ret=0
488  dig_with_opts +tcp @10.53.0.2 +subnet=0 A a.example > dig.out.test$n 2>&1 || ret=1
489  grep "status: NOERROR" < dig.out.test$n > /dev/null || ret=1
490  grep "CLIENT-SUBNET: 0.0.0.0/0/0" < dig.out.test$n > /dev/null || ret=1
491  grep "10.0.0.1" < dig.out.test$n > /dev/null || ret=1
492  check_ttl_range dig.out.test$n "A" 300 || ret=1
493  if [ $ret -ne 0 ]; then echo_i "failed"; fi
494  status=$((status+ret))
495
496  n=$((n+1))
497  echo_i "checking dig +subnet=::/0 ($n)"
498  ret=0
499  dig_with_opts +tcp @10.53.0.2 +subnet=::/0 A a.example > dig.out.test$n 2>&1 || ret=1
500  grep "status: NOERROR" < dig.out.test$n > /dev/null || ret=1
501  grep "CLIENT-SUBNET: ::/0/0" < dig.out.test$n > /dev/null || ret=1
502  grep "10.0.0.1" < dig.out.test$n > /dev/null || ret=1
503  check_ttl_range dig.out.test$n "A" 300 || ret=1
504  if [ $ret -ne 0 ]; then echo_i "failed"; fi
505  status=$((status+ret))
506
507  n=$((n+1))
508  echo_i "checking dig +ednsopt=8:00000000 (family=0, source=0, scope=0) ($n)"
509  ret=0
510  dig_with_opts +tcp @10.53.0.2 +ednsopt=8:00000000 A a.example > dig.out.test$n 2>&1 || ret=1
511  grep "status: NOERROR" < dig.out.test$n > /dev/null || ret=1
512  grep "CLIENT-SUBNET: 0/0/0" < dig.out.test$n > /dev/null || ret=1
513  grep "10.0.0.1" < dig.out.test$n > /dev/null || ret=1
514  check_ttl_range dig.out.test$n "A" 300 || ret=1
515  if [ $ret -ne 0 ]; then echo_i "failed"; fi
516  status=$((status+ret))
517
518  n=$((n+1))
519  echo_i "checking dig +ednsopt=8:00030000 (family=3, source=0, scope=0) ($n)"
520  ret=0
521  dig_with_opts +qr +tcp @10.53.0.2 +ednsopt=8:00030000 A a.example > dig.out.test$n 2>&1 || ret=1
522  grep "status: FORMERR" < dig.out.test$n > /dev/null || ret=1
523  grep "CLIENT-SUBNET: 00 03 00 00" < dig.out.test$n > /dev/null || ret=1
524  test "$(grep -c "CLIENT-SUBNET: 00 03 00 00" dig.out.test$n)" -eq 1 || ret=1
525  if [ $ret -ne 0 ]; then echo_i "failed"; fi
526  status=$((status+ret))
527
528  n=$((n+1))
529  echo_i "checking dig +subnet with prefix lengths between byte boundaries ($n)"
530  ret=0
531  for p in 9 10 11 12 13 14 15; do
532    dig_with_opts +tcp @10.53.0.2 +subnet=10.53/$p A a.example > dig.out.test.$p.$n 2>&1 || ret=1
533    grep "FORMERR" < dig.out.test.$p.$n > /dev/null && ret=1
534    grep "CLIENT-SUBNET.*/$p/0" < dig.out.test.$p.$n > /dev/null || ret=1
535    check_ttl_range dig.out.test.$p.$n "A" 300 || ret=1
536  done
537  if [ $ret -ne 0 ]; then echo_i "failed"; fi
538  status=$((status+ret))
539
540  n=$((n+1))
541  echo_i "checking dig +sp works as an abbreviated form of split ($n)"
542  ret=0
543  dig_with_opts @10.53.0.3 +sp=4 -t sshfp foo.example > dig.out.test$n || ret=1
544  grep " 9ABC DEF6 7890 " < dig.out.test$n > /dev/null || ret=1
545  check_ttl_range dig.out.test$n "SSHFP" 300 || ret=1
546  if [ $ret -ne 0 ]; then echo_i "failed"; fi
547  status=$((status+ret))
548
549  n=$((n+1))
550  echo_i "checking dig -c works ($n)"
551  ret=0
552  dig_with_opts @10.53.0.3 -c CHAOS -t txt version.bind > dig.out.test$n || ret=1
553  grep "version.bind.		0	CH	TXT" < dig.out.test$n > /dev/null || ret=1
554  if [ $ret -ne 0 ]; then echo_i "failed"; fi
555  status=$((status+ret))
556
557  n=$((n+1))
558  echo_i "checking dig +dscp ($n)"
559  ret=0
560  dig_with_opts @10.53.0.3 +dscp=32 a a.example > /dev/null 2>&1 || ret=1
561  dig_with_opts @10.53.0.3 +dscp=-1 a a.example > /dev/null 2>&1 && ret=1
562  dig_with_opts @10.53.0.3 +dscp=64 a a.example > /dev/null 2>&1 && ret=1
563  #TODO add a check to make sure dig is actually setting the dscp on the query
564  #we might have to add better logging to named for this
565  if [ $ret -ne 0 ]; then echo_i "failed"; fi
566  status=$((status+ret))
567
568  n=$((n+1))
569  echo_i "checking dig +ednsopt with option number ($n)"
570  ret=0
571  dig_with_opts @10.53.0.3 +ednsopt=3 a.example > dig.out.test$n 2>&1 || ret=1
572  grep 'NSID: .* ("ns3")' dig.out.test$n > /dev/null || ret=1
573  check_ttl_range dig.out.test$n "A" 300 || ret=1
574  if [ $ret -ne 0 ]; then echo_i "failed"; fi
575  status=$((status+ret))
576
577  n=$((n+1))
578  echo_i "checking dig +ednsopt with option name ($n)"
579  ret=0
580  dig_with_opts @10.53.0.3 +ednsopt=nsid a.example > dig.out.test$n 2>&1 || ret=1
581  grep 'NSID: .* ("ns3")' dig.out.test$n > /dev/null || ret=1
582  check_ttl_range dig.out.test$n "A" 300 || ret=1
583  if [ $ret -ne 0 ]; then echo_i "failed"; fi
584  status=$((status+ret))
585
586  n=$((n+1))
587  echo_i "checking ednsopt LLQ prints as expected ($n)"
588  ret=0
589  dig_with_opts @10.53.0.3 +ednsopt=llq:0001000200001234567812345678fefefefe +qr a.example > dig.out.test$n 2>&1 || ret=1
590  pat='LLQ: Version: 1, Opcode: 2, Error: 0, Identifier: 1311768465173141112, Lifetime: 4278124286$'
591  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
592  if [ $ret -ne 0 ]; then echo_i "failed"; fi
593  status=$((status+ret))
594
595  n=$((n+1))
596  echo_i "checking that dig warns about .local queries ($n)"
597  ret=0
598  dig_with_opts @10.53.0.3 local soa > dig.out.test$n 2>&1 || ret=1
599  grep ";; WARNING: .local is reserved for Multicast DNS" dig.out.test$n > /dev/null || ret=1
600  if [ $ret -ne 0 ]; then echo_i "failed"; fi
601  status=$((status+ret))
602
603  n=$((n+1))
604  echo_i "check that dig processes +ednsopt=key-tag and FORMERR is returned ($n)"
605  ret=0
606  dig_with_opts @10.53.0.3 +ednsopt=key-tag a.example +qr > dig.out.test$n 2>&1 || ret=1
607  grep "; KEY-TAG: *$" dig.out.test$n > /dev/null || ret=1
608  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
609  if [ $ret -ne 0 ]; then echo_i "failed"; fi
610  status=$((status+ret))
611
612  n=$((n+1))
613  echo_i "check that dig processes +ednsopt=key-tag:<value-list> ($n)"
614  ret=0
615  dig_with_opts @10.53.0.3 +ednsopt=key-tag:00010002 a.example +qr > dig.out.test$n 2>&1 || ret=1
616  grep "; KEY-TAG: 1, 2$" dig.out.test$n > /dev/null || ret=1
617  grep "status: FORMERR" dig.out.test$n > /dev/null && ret=1
618  check_ttl_range dig.out.test$n "A" 300 || ret=1
619  if [ $ret -ne 0 ]; then echo_i "failed"; fi
620  status=$((status+ret))
621
622  n=$((n+1))
623  echo_i "check that dig processes +ednsopt=key-tag:<malformed-value-list> and FORMERR is returned ($n)"
624  ret=0
625  dig_with_opts @10.53.0.3 +ednsopt=key-tag:0001000201 a.example +qr > dig.out.test$n 2>&1 || ret=1
626  grep "; KEY-TAG: 00 01 00 02 01" dig.out.test$n > /dev/null || ret=1
627  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
628  if [ $ret -ne 0 ]; then echo_i "failed"; fi
629  status=$((status+ret))
630
631  n=$((n+1))
632  echo_i "check that dig processes +ednsopt=client-tag:value ($n)"
633  ret=0
634  dig_with_opts @10.53.0.3 +ednsopt=client-tag:0001 a.example +qr > dig.out.test$n 2>&1 || ret=1
635  grep "; CLIENT-TAG: 1$" dig.out.test$n > /dev/null || ret=1
636  grep "status: FORMERR" dig.out.test$n > /dev/null && ret=1
637  if [ $ret -ne 0 ]; then echo_i "failed"; fi
638  status=$((status+ret))
639
640  n=$((n+1))
641  echo_i "check that FORMERR is returned for a too short client-tag ($n)"
642  ret=0
643  dig_with_opts @10.53.0.3 +ednsopt=client-tag:01 a.example +qr > dig.out.test$n 2>&1 || ret=1
644  grep "; CLIENT-TAG" dig.out.test$n > /dev/null || ret=1
645  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
646  if [ $ret -ne 0 ]; then echo_i "failed"; fi
647  status=$((status+ret))
648
649  n=$((n+1))
650  echo_i "check that FORMERR is returned for a too long client-tag ($n)"
651  ret=0
652  dig_with_opts @10.53.0.3 +ednsopt=client-tag:000001 a.example +qr > dig.out.test$n 2>&1 || ret=1
653  grep "; CLIENT-TAG" dig.out.test$n > /dev/null || ret=1
654  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
655  if [ $ret -ne 0 ]; then echo_i "failed"; fi
656  status=$((status+ret))
657
658  n=$((n+1))
659  echo_i "check that dig processes +ednsopt=server-tag:value ($n)"
660  ret=0
661  dig_with_opts @10.53.0.3 +ednsopt=server-tag:0001 a.example +qr > dig.out.test$n 2>&1 || ret=1
662  grep "; SERVER-TAG: 1$" dig.out.test$n > /dev/null || ret=1
663  grep "status: FORMERR" dig.out.test$n > /dev/null && ret=1
664  if [ $ret -ne 0 ]; then echo_i "failed"; fi
665  status=$((status+ret))
666
667  n=$((n+1))
668  echo_i "check that FORMERR is returned for a too short server-tag ($n)"
669  ret=0
670  dig_with_opts @10.53.0.3 +ednsopt=server-tag:01 a.example +qr > dig.out.test$n 2>&1 || ret=1
671  grep "; SERVER-TAG" dig.out.test$n > /dev/null || ret=1
672  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
673  if [ $ret -ne 0 ]; then echo_i "failed"; fi
674  status=$((status+ret))
675
676  n=$((n+1))
677  echo_i "check that FORMERR is returned for a too long server-tag ($n)"
678  ret=0
679  dig_with_opts @10.53.0.3 +ednsopt=server-tag:000001 a.example +qr > dig.out.test$n 2>&1 || ret=1
680  grep "; SERVER-TAG" dig.out.test$n > /dev/null || ret=1
681  grep "status: FORMERR" dig.out.test$n > /dev/null || ret=1
682  if [ $ret -ne 0 ]; then echo_i "failed"; fi
683  status=$((status+ret))
684
685  n=$((n+1))
686  echo_i "check that Extended DNS Error 0 is printed correctly ($n)"
687  # First defined EDE code, additional text "foo".
688  dig_with_opts @10.53.0.3 +ednsopt=ede:0000666f6f a.example +qr > dig.out.test$n 2>&1 || ret=1
689  pat='^; EDE: 0 (Other): (foo)$'
690  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
691  if [ $ret -ne 0 ]; then echo_i "failed"; fi
692  status=$((status+ret))
693
694  n=$((n+1))
695  echo_i "check that Extended DNS Error 24 is printed correctly ($n)"
696  # Last defined EDE code, no additional text.
697  dig_with_opts @10.53.0.3 +ednsopt=ede:0018 a.example +qr > dig.out.test$n 2>&1 || ret=1
698  pat='^; EDE: 24 (Invalid Data)$'
699  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
700  if [ $ret -ne 0 ]; then echo_i "failed"; fi
701  status=$((status+ret))
702
703  n=$((n+1))
704  echo_i "check that Extended DNS Error 25 is printed correctly ($n)"
705  # First undefined EDE code, additional text "foo".
706  dig_with_opts @10.53.0.3 +ednsopt=ede:0019666f6f a.example +qr > dig.out.test$n 2>&1 || ret=1
707  pat='^; EDE: 25: (foo)$'
708  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
709  if [ $ret -ne 0 ]; then echo_i "failed"; fi
710  status=$((status+ret))
711
712  n=$((n+1))
713  echo_i "check that invalid Extended DNS Error (length 0) is printed ($n)"
714  # EDE payload is too short
715  dig_with_opts @10.53.0.3 +ednsopt=ede a.example +qr > dig.out.test$n 2>&1 || ret=1
716  pat='^; EDE:$'
717  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
718  if [ $ret -ne 0 ]; then echo_i "failed"; fi
719  status=$((status+ret))
720
721  n=$((n+1))
722  echo_i "check that invalid Extended DNS Error (length 1) is printed ($n)"
723  # EDE payload is too short
724  dig_with_opts @10.53.0.3 +ednsopt=ede:00 a.example +qr > dig.out.test$n 2>&1 || ret=1
725  pat='^; EDE: 00 (".")$'
726  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
727  if [ $ret -ne 0 ]; then echo_i "failed"; fi
728  status=$((status+ret))
729
730  if [ $HAS_PYYAML -ne 0 ] ; then
731    n=$((n+1))
732    echo_i "check that +yaml Extended DNS Error 0 is printed correctly ($n)"
733    # First defined EDE code, additional text "foo".
734    dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0000666f6f a.example +qr > dig.out.test$n 2>&1 || ret=1
735    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE INFO-CODE > yamlget.out.test$n 2>&1 || ret=1
736    read -r value < yamlget.out.test$n
737    [ "$value" = "0 (Other)" ] || ret=1
738    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT > yamlget.out.test$n 2>&1 || ret=1
739    read -r value < yamlget.out.test$n
740    [ "$value" = "foo" ] || ret=1
741    if [ $ret -ne 0 ]; then echo_i "failed"; fi
742    status=$((status+ret))
743
744    n=$((n+1))
745    echo_i "check that +yaml Extended DNS Error 24 is printed correctly ($n)"
746    # Last defined EDE code, no additional text.
747    dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0018 a.example +qr > dig.out.test$n 2>&1 || ret=1
748    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE INFO-CODE > yamlget.out.test$n 2>&1 || ret=1
749    read -r value < yamlget.out.test$n
750    [ "$value" = "24 (Invalid Data)" ] || ret=1
751    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT > yamlget.out.test$n 2>&1 && ret=1
752    if [ $ret -ne 0 ]; then echo_i "failed"; fi
753    status=$((status+ret))
754
755    n=$((n+1))
756    echo_i "check that +yaml Extended DNS Error 25 is printed correctly ($n)"
757    # First undefined EDE code, additional text "foo".
758    dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:0019666f6f a.example +qr > dig.out.test$n 2>&1 || ret=1
759    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE INFO-CODE > yamlget.out.test$n 2>&1 || ret=1
760    read -r value < yamlget.out.test$n
761    [ "$value" = "25" ] || ret=1
762    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE EXTRA-TEXT > yamlget.out.test$n 2>&1 || ret=1
763    read -r value < yamlget.out.test$n
764    [ "$value" = "foo" ] || ret=1
765    if [ $ret -ne 0 ]; then echo_i "failed"; fi
766    status=$((status+ret))
767
768    n=$((n+1))
769    echo_i "check that invalid Extended DNS Error (length 0) is printed ($n)"
770    # EDE payload is too short
771    dig_with_opts @10.53.0.3 +yaml +ednsopt=ede a.example +qr > dig.out.test$n 2>&1 || ret=1
772    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE > yamlget.out.test$n 2>&1 || ret=1
773    read -r value < yamlget.out.test$n
774    [ "$value" = "None" ] || ret=1
775    if [ $ret -ne 0 ]; then echo_i "failed"; fi
776    status=$((status+ret))
777
778    n=$((n+1))
779    echo_i "check that invalid +yaml Extended DNS Error (length 1) is printed ($n)"
780    # EDE payload is too short
781    dig_with_opts @10.53.0.3 +yaml +ednsopt=ede:00 a.example +qr > dig.out.test$n 2>&1 || ret=1
782    $PYTHON yamlget.py dig.out.test$n 0 message query_message_data OPT_PSEUDOSECTION EDNS EDE > yamlget.out.test$n 2>&1 || ret=1
783    read -r value < yamlget.out.test$n
784    [ "$value" = '00 (".")' ] || ret=1
785    if [ $ret -ne 0 ]; then echo_i "failed"; fi
786    status=$((status+ret))
787  fi
788
789  n=$((n+1))
790  echo_i "check that dig handles malformed option '+ednsopt=:' gracefully ($n)"
791  ret=0
792  dig_with_opts @10.53.0.3 +ednsopt=: a.example > dig.out.test$n 2>&1 && ret=1
793  grep "ednsopt no code point specified" dig.out.test$n > /dev/null || ret=1
794  if [ $ret -ne 0 ]; then echo_i "failed"; fi
795  status=$((status+ret))
796
797  n=$((n+1))
798  echo_i "check that dig gracefully handles bad escape in domain name ($n)"
799  ret=0
800  digstatus=0
801  dig_with_opts @10.53.0.3 '\0.' > dig.out.test$n 2>&1 || digstatus=$?
802  echo digstatus=$digstatus >> dig.out.test$n
803  test $digstatus -eq 10 || ret=1
804  grep REQUIRE dig.out.test$n > /dev/null && ret=1
805  grep "is not a legal name (bad escape)" dig.out.test$n > /dev/null || ret=1
806  if [ $ret -ne 0 ]; then echo_i "failed"; fi
807  status=$((status+ret))
808
809  n=$((n+1))
810  echo_i "check that dig -q -m works ($n)"
811  ret=0
812  dig_with_opts @10.53.0.3 -q -m > dig.out.test$n 2>&1
813  pat='^;-m\..*IN.*A$'
814  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
815  grep "Dump of all outstanding memory allocations" dig.out.test$n > /dev/null && ret=1
816  if [ $ret -ne 0 ]; then echo_i "failed"; fi
817  status=$((status+ret))
818
819  n=$((n+1))
820  echo_i "checking exit code for a retry upon TCP EOF (immediate -> immediate) ($n)"
821  ret=0
822  echo "no_response no_response" | sendcmd 10.53.0.5
823  dig_with_opts @10.53.0.5 example AXFR +tries=2 > dig.out.test$n 2>&1 && ret=1
824  # Sanity check: ensure ans5 behaves as expected.
825  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 2 ] || ret=1
826  if [ $ret -ne 0 ]; then echo_i "failed"; fi
827  status=$((status+ret))
828
829  n=$((n+1))
830  echo_i "checking exit code for a retry upon TCP EOF (partial AXFR -> partial AXFR) ($n)"
831  ret=0
832  echo "partial_axfr partial_axfr" | sendcmd 10.53.0.5
833  dig_with_opts @10.53.0.5 example AXFR +tries=2 > dig.out.test$n 2>&1 && ret=1
834  # Sanity check: ensure ans5 behaves as expected.
835  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 2 ] || ret=1
836  if [ $ret -ne 0 ]; then echo_i "failed"; fi
837  status=$((status+ret))
838
839  n=$((n+1))
840  echo_i "checking exit code for a retry upon TCP EOF (immediate -> partial AXFR) ($n)"
841  ret=0
842  echo "no_response partial_axfr" | sendcmd 10.53.0.5
843  dig_with_opts @10.53.0.5 example AXFR +tries=2 > dig.out.test$n 2>&1 && ret=1
844  # Sanity check: ensure ans5 behaves as expected.
845  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 2 ] || ret=1
846  if [ $ret -ne 0 ]; then echo_i "failed"; fi
847  status=$((status+ret))
848
849  n=$((n+1))
850  echo_i "checking exit code for a retry upon TCP EOF (partial AXFR -> immediate) ($n)"
851  ret=0
852  echo "partial_axfr no_response" | sendcmd 10.53.0.5
853  dig_with_opts @10.53.0.5 example AXFR +tries=2 > dig.out.test$n 2>&1 && ret=1
854  # Sanity check: ensure ans5 behaves as expected.
855  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 2 ] || ret=1
856  if [ $ret -ne 0 ]; then echo_i "failed"; fi
857  status=$((status+ret))
858
859  n=$((n+1))
860  echo_i "checking exit code for a retry upon TCP EOF (immediate -> complete AXFR) ($n)"
861  ret=0
862  echo "no_response complete_axfr" | sendcmd 10.53.0.5
863  dig_with_opts @10.53.0.5 example AXFR +tries=2 > dig.out.test$n 2>&1 || ret=1
864  # Sanity check: ensure ans5 behaves as expected.
865  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 1 ] || ret=1
866  if [ $ret -ne 0 ]; then echo_i "failed"; fi
867  status=$((status+ret))
868
869  n=$((n+1))
870  echo_i "checking exit code for a retry upon TCP EOF (partial AXFR -> complete AXFR) ($n)"
871  ret=0
872  echo "partial_axfr complete_axfr" | sendcmd 10.53.0.5
873  dig_with_opts @10.53.0.5 example AXFR +tries=2 > dig.out.test$n 2>&1 || ret=1
874  # Sanity check: ensure ans5 behaves as expected.
875  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 1 ] || ret=1
876  if [ $ret -ne 0 ]; then echo_i "failed"; fi
877  status=$((status+ret))
878
879  n=$((n+1))
880  echo_i "checking +tries=1 won't retry twice upon TCP EOF ($n)"
881  ret=0
882  echo "no_response no_response" | sendcmd 10.53.0.5
883  dig_with_opts @10.53.0.5 example AXFR +tries=1 > dig.out.test$n 2>&1 && ret=1
884  # Sanity check: ensure ans5 behaves as expected.
885  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 1 ] || ret=1
886  if [ $ret -ne 0 ]; then echo_i "failed"; fi
887  status=$((status+ret))
888
889  n=$((n+1))
890  echo_i "checking +retry=0 won't retry twice upon TCP EOF ($n)"
891  ret=0
892  dig_with_opts @10.53.0.5 example AXFR +retry=0 > dig.out.test$n 2>&1 && ret=1
893  # Sanity check: ensure ans5 behaves as expected.
894  [ `grep "communications error.*end of file" dig.out.test$n | wc -l` -eq 1 ] || ret=1
895  if [ $ret -ne 0 ]; then echo_i "failed"; fi
896  status=$((status+ret))
897
898  n=$((n+1))
899  echo_i "check that dig +expandaaaa works ($n)"
900  ret=0
901  dig_with_opts @10.53.0.3 +expandaaaa AAAA ns2.example > dig.out.test$n 2>&1 || ret=1
902  grep "ns2.example.*fd92:7065:0b8e:ffff:0000:0000:0000:0002" dig.out.test$n > /dev/null || ret=1
903  if [ $ret -ne 0 ]; then echo_i "failed"; fi
904  status=$((status+ret))
905
906  n=$((n+1))
907  echo_i "check that dig +noexpandaaaa works ($n)"
908  ret=0
909  dig_with_opts @10.53.0.3 +noexpandaaaa AAAA ns2.example > dig.out.test$n 2>&1 || ret=1
910  grep "ns2.example.*fd92:7065:b8e:ffff::2" dig.out.test$n > /dev/null || ret=1
911  if [ $ret -ne 0 ]; then echo_i "failed"; fi
912  status=$((status+ret))
913
914  n=$((n+1))
915  echo_i "check that dig default for +[no]expandaaa (+noexpandaaaa) works ($n)"
916  ret=0
917  dig_with_opts @10.53.0.3 AAAA ns2.example > dig.out.test$n 2>&1 || ret=1
918  grep "ns2.example.*fd92:7065:b8e:ffff::2" dig.out.test$n > /dev/null || ret=1
919  if [ $ret -ne 0 ]; then echo_i "failed"; fi
920  status=$((status+ret))
921
922  n=$((n+1))
923
924  echo_i "check that dig +short +expandaaaa works ($n)"
925  ret=0
926  dig_with_opts @10.53.0.3 +short +expandaaaa AAAA ns2.example > dig.out.test$n 2>&1 || ret=1
927  pat='^fd92:7065:0b8e:ffff:0000:0000:0000:0002$'
928  tr -d '\r' < dig.out.test$n | grep "$pat" > /dev/null || ret=1
929  if [ $ret -ne 0 ]; then echo_i "failed"; fi
930  status=$((status+ret))
931
932  if [ $HAS_PYYAML -ne 0 ] ; then
933    n=$((n+1))
934    echo_i "check dig +yaml output ($n)"
935    ret=0
936    dig_with_opts +qr +yaml @10.53.0.3 any ns2.example > dig.out.test$n 2>&1 || ret=1
937    value=$($PYTHON yamlget.py dig.out.test$n 0 message query_message_data status || ret=1)
938    [ "$value" = "NOERROR" ] || ret=1
939    value=$($PYTHON yamlget.py dig.out.test$n 1 message response_message_data status || ret=1)
940    [ "$value" = "NOERROR" ] || ret=1
941    value=$($PYTHON yamlget.py dig.out.test$n 1 message response_message_data QUESTION_SECTION 0 || ret=1)
942    [ "$value" = "ns2.example. IN ANY" ] || ret=1
943    if [ $ret -ne 0 ]; then echo_i "failed"; fi
944    status=$((status+ret))
945
946    n=$((n+1))
947    echo_i "check dig +yaml output of an IPv6 address ending in zeroes ($n)"
948    ret=0
949    dig_with_opts +qr +yaml @10.53.0.3 aaaa d.example > dig.out.test$n 2>&1 || ret=1
950    $PYTHON yamlget.py dig.out.test$n 1 message response_message_data ANSWER_SECTION 0 > yamlget.out.test$n 2>&1 || ret=1
951    read -r value < yamlget.out.test$n
952    [ "$value" = "d.example. 300 IN AAAA fd92:7065:b8e:ffff::0" ] || ret=1
953    if [ $ret -ne 0 ]; then echo_i "failed"; fi
954    status=$((status+ret))
955  fi
956
957  n=$((n+1))
958  echo_i "check that dig +unexpected works ($n)"
959  ret=0
960  dig_with_opts @10.53.0.6 +unexpected a a.example > dig.out.test$n || ret=1
961  grep 'reply from unexpected source' dig.out.test$n > /dev/null || ret=1
962  grep 'status: NOERROR' dig.out.test$n > /dev/null || ret=1
963  if [ $ret -ne 0 ]; then echo_i "failed"; fi
964  status=$((status+ret))
965
966  n=$((n+1))
967  echo_i "check that dig +nounexpected works ($n)"
968  ret=0
969  dig_with_opts @10.53.0.6 +nounexpected +tries=1 +time=2 a a.example > dig.out.test$n && ret=1
970  grep 'reply from unexpected source' dig.out.test$n > /dev/null || ret=1
971  grep "status: NOERROR" < dig.out.test$n > /dev/null && ret=1
972  if [ $ret -ne 0 ]; then echo_i "failed"; fi
973  status=$((status+ret))
974
975  n=$((n+1))
976  echo_i "check that dig default for +[no]unexpected (+nounexpected) works ($n)"
977  ret=0
978  dig_with_opts @10.53.0.6 +tries=1 +time=2 a a.example > dig.out.test$n && ret=1
979  grep 'reply from unexpected source' dig.out.test$n > /dev/null || ret=1
980  grep "status: NOERROR" < dig.out.test$n > /dev/null && ret=1
981  if [ $ret -ne 0 ]; then echo_i "failed"; fi
982  status=$((status+ret))
983
984  n=$((n+1))
985  echo_i "check that dig +bufsize=0 disables EDNS ($n)"
986  ret=0
987  dig_with_opts @10.53.0.3 a.example +bufsize=0 +qr > dig.out.test$n 2>&1 || ret=1
988  grep "EDNS:" dig.out.test$n > /dev/null && ret=1
989  if [ $ret -ne 0 ]; then echo_i "failed"; fi
990  status=$((status+ret))
991
992  n=$((n+1))
993  echo_i "check that dig +bufsize=0 +edns sends EDNS with bufsize of 0 ($n)"
994  ret=0
995  dig_with_opts @10.53.0.3 a.example +bufsize=0 +edns +qr > dig.out.test$n 2>&1 || ret=1
996  pat='EDNS:.* udp: 0$'
997  tr -d '\r' < dig.out.test$n | grep -E "$pat" > /dev/null || ret=1
998  if [ $ret -ne 0 ]; then echo_i "failed"; fi
999  status=$((status+ret))
1000
1001  n=$((n+1))
1002  echo_i "check that dig +bufsize restores default bufsize ($n)"
1003  ret=0
1004  dig_with_opts @10.53.0.3 a.example +bufsize=0 +bufsize +qr > dig.out.test$n 2>&1 || ret=1
1005  lines1232=`grep "EDNS:.* udp: 1232" dig.out.test$n | wc -l`
1006  lines4096=`grep "EDNS:.* udp: 4096" dig.out.test$n | wc -l`
1007  test $lines1232 -eq 1 || ret=1
1008  test $lines4096 -eq 1 || ret=1
1009  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1010  status=$((status+ret))
1011
1012  n=$((n+1))
1013  echo_i "check that dig without -u displays 'Query time' in millseconds ($n)"
1014  ret=0
1015  dig_with_opts @10.53.0.3 a.example > dig.out.test$n 2>&1 || ret=1
1016  grep ';; Query time: [0-9][0-9]* msec' dig.out.test$n >/dev/null || ret=1
1017  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1018  status=$((status+ret))
1019
1020  n=$((n+1))
1021  echo_i "check that dig -u displays 'Query time' in microseconds ($n)"
1022  ret=0
1023  dig_with_opts -u @10.53.0.3 a.example > dig.out.test$n 2>&1 || ret=1
1024  grep ';; Query time: [0-9][0-9]* usec' dig.out.test$n >/dev/null || ret=1
1025  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1026  status=$((status+ret))
1027
1028  n=$((n+1))
1029  echo_i "check that dig +yaml without -u displays timestamps in milliseconds ($n)"
1030  ret=0
1031  dig_with_opts +yaml @10.53.0.3 a.example > dig.out.test$n 2>&1 || ret=1
1032  grep 'query_time: !!timestamp ....-..-..T..:..:..\....Z' dig.out.test$n >/dev/null || ret=1
1033  grep 'response_time: !!timestamp ....-..-..T..:..:..\....Z' dig.out.test$n >/dev/null || ret=1
1034  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1035  status=$((status+ret))
1036
1037  n=$((n+1))
1038  echo_i "check that dig -u +yaml displays timestamps in microseconds ($n)"
1039  ret=0
1040  dig_with_opts -u +yaml @10.53.0.3 a.example > dig.out.test$n 2>&1 || ret=1
1041  grep 'query_time: !!timestamp ....-..-..T..:..:..\.......Z' dig.out.test$n >/dev/null || ret=1
1042  grep 'response_time: !!timestamp ....-..-..T..:..:..\.......Z' dig.out.test$n >/dev/null || ret=1
1043  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1044  status=$((status+ret))
1045
1046else
1047  echo_i "$DIG is needed, so skipping these dig tests"
1048fi
1049
1050if [ -x "$MDIG" ] ; then
1051  n=$((n+1))
1052  echo_i "check that mdig handles malformed option '+ednsopt=:' gracefully ($n)"
1053  ret=0
1054  mdig_with_opts @10.53.0.3 +ednsopt=: a.example > dig.out.test$n 2>&1 && ret=1
1055  grep "ednsopt no code point specified" dig.out.test$n > /dev/null || ret=1
1056  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1057  status=$((status+ret))
1058
1059  n=$((n+1))
1060  echo_i "checking mdig +multi +norrcomments works for DNSKEY (when default is rrcomments)($n)"
1061  ret=0
1062  mdig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t DNSKEY example > dig.out.test$n || ret=1
1063  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" dig.out.test$n && ret=1
1064  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1065  status=$((status+ret))
1066
1067  n=$((n+1))
1068  echo_i "checking mdig +multi +norrcomments works for SOA (when default is rrcomments)($n)"
1069  ret=0
1070  mdig_with_opts +tcp @10.53.0.3 +multi +norrcomments -t SOA example > dig.out.test$n || ret=1
1071  grep "; serial" < dig.out.test$n > /dev/null && ret=1
1072  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1073  status=$((status+ret))
1074
1075  if [ $HAS_PYYAML -ne 0 ] ; then
1076    n=$((n+1))
1077    echo_i "check mdig +yaml output ($n)"
1078    ret=0
1079    mdig_with_opts +yaml @10.53.0.3 -t any ns2.example > dig.out.test$n 2>&1 || ret=1
1080    value=$($PYTHON yamlget.py dig.out.test$n 0 message response_message_data status || ret=1)
1081    [ "$value" = "NOERROR" ] || ret=1
1082    value=$($PYTHON yamlget.py dig.out.test$n 0 message response_message_data QUESTION_SECTION 0 || ret=1)
1083    [ "$value" = "ns2.example. IN ANY" ] || ret=1
1084    if [ $ret -ne 0 ]; then echo_i "failed"; fi
1085    status=$((status+ret))
1086  fi
1087else
1088  echo_i "$MDIG is needed, so skipping these mdig tests"
1089fi
1090
1091if [ -x "$DELV" ] ; then
1092  n=$((n+1))
1093  echo_i "checking delv short form works ($n)"
1094  ret=0
1095  delv_with_opts @10.53.0.3 +short a a.example > delv.out.test$n || ret=1
1096  test "$(wc -l < delv.out.test$n)" -eq 1 || ret=1
1097  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1098  status=$((status+ret))
1099
1100  n=$((n+1))
1101  echo_i "checking delv split width works ($n)"
1102  ret=0
1103  delv_with_opts @10.53.0.3 +split=4 -t sshfp foo.example > delv.out.test$n || ret=1
1104  grep " 9ABC DEF6 7890 " < delv.out.test$n > /dev/null || ret=1
1105  check_ttl_range delv.out.test$n "SSHFP" 300 || ret=1
1106  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1107  status=$((status+ret))
1108
1109  n=$((n+1))
1110  echo_i "checking delv +unknownformat works ($n)"
1111  ret=0
1112  delv_with_opts @10.53.0.3 +unknownformat a a.example > delv.out.test$n || ret=1
1113  grep "CLASS1[ 	][ 	]*TYPE1[ 	][ 	]*\\\\# 4 0A000001" < delv.out.test$n > /dev/null || ret=1
1114  check_ttl_range delv.out.test$n "TYPE1" 300 || ret=1
1115  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1116  status=$((status+ret))
1117
1118  n=$((n+1))
1119  echo_i "checking delv -4 -6 ($n)"
1120  ret=0
1121  delv_with_opts @10.53.0.3 -4 -6 A a.example > delv.out.test$n 2>&1 && ret=1
1122  grep "only one of -4 and -6 allowed" < delv.out.test$n > /dev/null || ret=1
1123  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1124  status=$((status+ret))
1125
1126  n=$((n+1))
1127  echo_i "checking delv with IPv6 on IPv4 does not work ($n)"
1128  if testsock6 fd92:7065:b8e:ffff::3 2>/dev/null
1129  then
1130    ret=0
1131    # following should fail because @IPv4 overrides earlier @IPv6 above
1132    # and -6 forces IPv6 so this should fail, with a message
1133    # "Use of IPv4 disabled by -6"
1134    delv_with_opts @fd92:7065:b8e:ffff::3 @10.53.0.3 -6 -t txt foo.example > delv.out.test$n 2>&1 && ret=1
1135    # it should have no results but error output
1136    grep "testing" < delv.out.test$n > /dev/null && ret=1
1137    grep "Use of IPv4 disabled by -6" delv.out.test$n > /dev/null || ret=1
1138    if [ $ret -ne 0 ]; then echo_i "failed"; fi
1139    status=$((status+ret))
1140  else
1141    echo_i "IPv6 unavailable; skipping"
1142  fi
1143
1144  n=$((n+1))
1145  echo_i "checking delv with IPv4 on IPv6 does not work ($n)"
1146  if testsock6 fd92:7065:b8e:ffff::3 2>/dev/null
1147  then
1148    ret=0
1149    # following should fail because @IPv6 overrides earlier @IPv4 above
1150    # and -4 forces IPv4 so this should fail, with a message
1151    # "Use of IPv6 disabled by -4"
1152    delv_with_opts @10.53.0.3 @fd92:7065:b8e:ffff::3 -4 -t txt foo.example > delv.out.test$n 2>&1 && ret=1
1153    # it should have no results but error output
1154    grep "testing" delv.out.test$n > /dev/null && ret=1
1155    grep "Use of IPv6 disabled by -4" delv.out.test$n > /dev/null || ret=1
1156    if [ $ret -ne 0 ]; then echo_i "failed"; fi
1157    status=$((status+ret))
1158  else
1159    echo_i "IPv6 unavailable; skipping"
1160  fi
1161
1162  n=$((n+1))
1163  echo_i "checking delv with reverse lookup works ($n)"
1164  ret=0
1165  delv_with_opts @10.53.0.3 -x 127.0.0.1 > delv.out.test$n 2>&1 || ret=1
1166  # doesn't matter if has answer
1167  grep -i "127\\.in-addr\\.arpa\\." < delv.out.test$n > /dev/null || ret=1
1168  check_ttl_range delv.out.test$n '\\-ANY' 10800 3 || ret=1
1169  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1170  status=$((status+ret))
1171
1172  n=$((n+1))
1173  echo_i "checking delv over TCP works ($n)"
1174  ret=0
1175  delv_with_opts +tcp @10.53.0.3 a a.example > delv.out.test$n || ret=1
1176  grep "10\\.0\\.0\\.1$" < delv.out.test$n > /dev/null || ret=1
1177  check_ttl_range delv.out.test$n "A" 300 || ret=1
1178  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1179  status=$((status+ret))
1180
1181  n=$((n+1))
1182  echo_i "checking delv +multi +norrcomments works for DNSKEY (when default is rrcomments)($n)"
1183  ret=0
1184  delv_with_opts +tcp @10.53.0.3 +multi +norrcomments DNSKEY example > delv.out.test$n || ret=1
1185  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" < delv.out.test$n > /dev/null && ret=1
1186  check_ttl_range delv.out.test$n "DNSKEY" 300 || ret=1
1187  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1188  status=$((status+ret))
1189
1190  n=$((n+1))
1191  echo_i "checking delv +multi +norrcomments works for SOA (when default is rrcomments)($n)"
1192  ret=0
1193  delv_with_opts +tcp @10.53.0.3 +multi +norrcomments SOA example > delv.out.test$n || ret=1
1194  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" < delv.out.test$n > /dev/null && ret=1
1195  check_ttl_range delv.out.test$n "SOA" 300 || ret=1
1196  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1197  status=$((status+ret))
1198
1199  n=$((n+1))
1200  echo_i "checking delv +rrcomments works for DNSKEY($n)"
1201  ret=0
1202  delv_with_opts +tcp @10.53.0.3 +rrcomments DNSKEY example > delv.out.test$n || ret=1
1203  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" < delv.out.test$n > /dev/null || ret=1
1204  check_ttl_range delv.out.test$n "DNSKEY" 300 || ret=1
1205  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1206  status=$((status+ret))
1207
1208  n=$((n+1))
1209  echo_i "checking delv +short +rrcomments works for DNSKEY ($n)"
1210  ret=0
1211  delv_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example > delv.out.test$n || ret=1
1212  grep "; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" < delv.out.test$n > /dev/null || ret=1
1213  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1214  status=$((status+ret))
1215
1216  n=$((n+1))
1217  echo_i "checking delv +short +rrcomments works ($n)"
1218  ret=0
1219  delv_with_opts +tcp @10.53.0.3 +short +rrcomments DNSKEY example > delv.out.test$n || ret=1
1220  grep -q "$KEYDATA  ; ZSK; alg = $DEFAULT_ALGORITHM ; key id = $KEYID" < delv.out.test$n || ret=1
1221  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1222  status=$((status+ret))
1223
1224  n=$((n+1))
1225  echo_i "checking delv +short +nosplit works ($n)"
1226  ret=0
1227  delv_with_opts +tcp @10.53.0.3 +short +nosplit DNSKEY example > delv.out.test$n || ret=1
1228  grep -q "$NOSPLIT" < delv.out.test$n || ret=1
1229  test "$(wc -l < delv.out.test$n)" -eq 1 || ret=1
1230  test "$(awk '{print NF}' < delv.out.test$n)" -eq 14 || ret=1
1231  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1232  status=$((status+ret))
1233
1234  n=$((n+1))
1235  echo_i "checking delv +short +nosplit +norrcomments works ($n)"
1236  ret=0
1237  delv_with_opts +tcp @10.53.0.3 +short +nosplit +norrcomments DNSKEY example > delv.out.test$n || ret=1
1238  grep -q "$NOSPLIT\$" < delv.out.test$n || ret=1
1239  test "$(wc -l < delv.out.test$n)" -eq 1 || ret=1
1240  test "$(awk '{print NF}' < delv.out.test$n)" -eq 4 || ret=1
1241  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1242  status=$((status+ret))
1243
1244  n=$((n+1))
1245  echo_i "checking delv +sp works as an abbriviated form of split ($n)"
1246  ret=0
1247  delv_with_opts @10.53.0.3 +sp=4 -t sshfp foo.example > delv.out.test$n || ret=1
1248  grep " 9ABC DEF6 7890 " < delv.out.test$n > /dev/null || ret=1
1249  check_ttl_range delv.out.test$n "SSHFP" 300 || ret=1
1250  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1251  status=$((status+ret))
1252
1253  n=$((n+1))
1254  echo_i "checking delv +sh works as an abbriviated form of short ($n)"
1255  ret=0
1256  delv_with_opts @10.53.0.3 +sh a a.example > delv.out.test$n || ret=1
1257  test "$(wc -l < delv.out.test$n)" -eq 1 || ret=1
1258  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1259  status=$((status+ret))
1260
1261  n=$((n+1))
1262  echo_i "checking delv -c IN works ($n)"
1263  ret=0
1264  delv_with_opts @10.53.0.3 -c IN -t a a.example > delv.out.test$n || ret=1
1265  grep "a.example." < delv.out.test$n > /dev/null || ret=1
1266  check_ttl_range delv.out.test$n "A" 300 || ret=1
1267  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1268  status=$((status+ret))
1269
1270  n=$((n+1))
1271  echo_i "checking delv -c CH is ignored, and treated like IN ($n)"
1272  ret=0
1273  delv_with_opts @10.53.0.3 -c CH -t a a.example > delv.out.test$n || ret=1
1274  grep "a.example." < delv.out.test$n > /dev/null || ret=1
1275  check_ttl_range delv.out.test$n "A" 300 || ret=1
1276  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1277  status=$((status+ret))
1278
1279  n=$((n+1))
1280  echo_i "checking delv H is ignored, and treated like IN ($n)"
1281  ret=0
1282  delv_with_opts @10.53.0.3 -c CH -t a a.example > delv.out.test$n || ret=1
1283  grep "a.example." < delv.out.test$n > /dev/null || ret=1
1284  check_ttl_range delv.out.test$n "A" 300 || ret=1
1285  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1286  status=$((status+ret))
1287
1288  n=$((n+1))
1289  echo_i "check that delv -q -m works ($n)"
1290  ret=0
1291  delv_with_opts @10.53.0.3 -q -m > delv.out.test$n 2>&1 || ret=1
1292  grep '^; -m\..*[0-9]*.*IN.*ANY.*;' delv.out.test$n > /dev/null || ret=1
1293  grep "^add " delv.out.test$n > /dev/null && ret=1
1294  grep "^del " delv.out.test$n > /dev/null && ret=1
1295  check_ttl_range delv.out.test$n '\\-ANY' 300 3 || ret=1
1296  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1297  status=$((status+ret))
1298
1299  n=$((n+1))
1300  echo_i "check that delv -t ANY works ($n)"
1301  ret=0
1302  delv_with_opts @10.53.0.3 -t ANY example > delv.out.test$n 2>&1 || ret=1
1303  grep "^example." < delv.out.test$n > /dev/null || ret=1
1304  check_ttl_range delv.out.test$n NS 300 || ret=1
1305  check_ttl_range delv.out.test$n SOA 300 || ret=1
1306  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1307  status=$((status+ret))
1308
1309  n=$((n+1))
1310  echo_i "check that delv loads key-style trust anchors ($n)"
1311  ret=0
1312  delv_with_opts -a ns3/anchor.dnskey +root=example @10.53.0.3 -t DNSKEY example > delv.out.test$n 2>&1 || ret=1
1313  grep "fully validated" delv.out.test$n > /dev/null || ret=1
1314  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1315  status=$((status+ret))
1316
1317  n=$((n+1))
1318  echo_i "check that delv loads DS-style trust anchors ($n)"
1319  ret=0
1320  delv_with_opts -a ns3/anchor.ds +root=example @10.53.0.3 -t DNSKEY example > delv.out.test$n 2>&1 || ret=1
1321  grep "fully validated" delv.out.test$n > /dev/null || ret=1
1322  if [ $ret -ne 0 ]; then echo_i "failed"; fi
1323  status=$((status+ret))
1324
1325  if [ $HAS_PYYAML -ne 0 ] ; then
1326    n=$((n+1))
1327    echo_i "check delv +yaml output ($n)"
1328    ret=0
1329    delv_with_opts +yaml @10.53.0.3 any ns2.example > delv.out.test$n 2>&1 || ret=1
1330    value=$($PYTHON yamlget.py delv.out.test$n status || ret=1)
1331    [ "$value" = "success" ] || ret=1
1332    value=$($PYTHON yamlget.py delv.out.test$n query_name || ret=1)
1333    [ "$value" = "ns2.example" ] || ret=1
1334    value=$($PYTHON yamlget.py delv.out.test$n records 0 answer_not_validated 0 || ret=1)
1335    count=$(echo $value | wc -w )
1336    [ ${count:-0} -eq 5 ] || ret=1
1337    if [ $ret -ne 0 ]; then echo_i "failed"; fi
1338    status=$((status+ret))
1339  fi
1340else
1341  echo_i "$DELV is needed, so skipping these delv tests"
1342fi
1343
1344echo_i "exit status: $status"
1345[ $status -eq 0 ] || exit 1
1346