That's one way to< deal with what's arguably a shortcoming in nslookup. Another is just to chuck nslookup and use dig, the Domain Information Groper (a reverse-engineered acronym if we've ever heard one). dig is a powerful DNS query tool that comes with BIND. Unfortunately, it isn't shipped with Windows Server 2003, but you can get a version of dig that runs on Windows NT, Windows 2000, and Windows Server 2003 from ftp://ftp.isc.org/isc/bind/contrib/ntbind-8.4.1/BIND8.4.1Tools.zip. You may also need to download the other DLLs available at ftp://ftp.isc.org/isc/bind/contrib/ntbind-8.4.1. Follow the installation instructions in the readme1sttools.txt file and note the Known Problems section of that file. It tells you, for example, that on Windows 2000 and Windows Server 2003, dig can't read the resolver configuration from the Registry, so it has no idea what name servers to query by default. You'll need to create the file %SystemRoot%\system32\drivers\etc\resolv.conf that contains at least one line specifying a name server to query:
Now, all this might seem like a lot of trouble when nslookup is already installed. But for our DNS troubleshooting purposes, we left nslookup in the dust years ago. We hope you'll come to appreciate dig as much as we do.
With dig, you specify all aspects of the query you'd like to send on the command line; there's no interactive mode. You specify the domain name you want to look up as an argument, and the type of query you want to send (e.g., a for address records, mx for MX records) as another argument; the default is to look up address records. You specify the name server you'd like to query after an "@." You can use either a domain name or an IP address to designate a name server.
dig is smart about arguments, too. You can specify the arguments in any order you like, and dig will figure out that mx is probably the type of record, not the domain name, you want to look up.
One major difference between nslookup and dig is that dig doesn't apply the search list so always give dig fully qualified domain names as arguments. So:
C:\> dig plan9.fx.movie.edu
looks up address records for plan9.fx.movie.edu using the first name server in resolv.conf, while:
C:\> dig acmebw.com mx
looks up MX records for acmebw.com on the same name server, and:
C:\> dig @wormhole.movie.edu. movie.edu. soa
queries wormhole.movie.edu for the SOA record of movie.edu.
dig shows you the complete DNS response message in all its glory with the various sections (header, question, answer, authority, and additional) clearly called out, and with resource records in those sections printed in master file format. This can come in handy if you need to use some of your troubleshooting tool's output in a zone datafile or in your root hints file. For example, the output produced by:
C:\> dig @a.root-servers.net ns .
looks like this:
; <<>> DiG 8.4 <<>> @a.root-servers.net ns . ; (1 server found) ;; res options: init recurs defnam dnsrch ;; got answer: ;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 13297 ;; flags: qr aa rd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 13 ;; QUERY SECTION: ;; ., type = NS, class = IN ;; ANSWER SECTION: . 6D IN NS A.ROOT-SERVERS.NET. . 6D IN NS H.ROOT-SERVERS.NET. . 6D IN NS C.ROOT-SERVERS.NET. . 6D IN NS G.ROOT-SERVERS.NET. . 6D IN NS F.ROOT-SERVERS.NET. . 6D IN NS B.ROOT-SERVERS.NET. . 6D IN NS J.ROOT-SERVERS.NET. . 6D IN NS K.ROOT-SERVERS.NET. . 6D IN NS L.ROOT-SERVERS.NET. . 6D IN NS M.ROOT-SERVERS.NET. . 6D IN NS I.ROOT-SERVERS.NET. . 6D IN NS E.ROOT-SERVERS.NET. . 6D IN NS D.ROOT-SERVERS.NET. ;; ADDITIONAL SECTION: A.ROOT-SERVERS.NET. 5w6d16h IN A 188.8.131.52 H.ROOT-SERVERS.NET. 5w6d16h IN A 184.108.40.206 C.ROOT-SERVERS.NET. 5w6d16h IN A 220.127.116.11 G.ROOT-SERVERS.NET. 5w6d16h IN A 18.104.22.168 F.ROOT-SERVERS.NET. 5w6d16h IN A 22.214.171.124 B.ROOT-SERVERS.NET. 5w6d16h IN A 126.96.36.199 J.ROOT-SERVERS.NET. 5w6d16h IN A 188.8.131.52 K.ROOT-SERVERS.NET. 5w6d16h IN A 184.108.40.206 L.ROOT-SERVERS.NET. 5w6d16h IN A 220.127.116.11 M.ROOT-SERVERS.NET. 5w6d16h IN A 18.104.22.168 I.ROOT-SERVERS.NET. 5w6d16h IN A 22.214.171.124 E.ROOT-SERVERS.NET. 5w6d16h IN A 126.96.36.199 D.ROOT-SERVERS.NET. 5w6d16h IN A 188.8.131.52 ;; Total query time: 0 msec ;; FROM: typhoon to SERVER: 184.108.40.206 ;; WHEN: Tue Aug 12 14:48:50 2003 ;; MSG SIZE sent: 17 rcvd: 436
Let's examine this output section by section.
The first line, beginning with the master file comment character (;) and <<>> DiG 8.4 <<>>, simply parrots the options we specified in the command line, namely, that we were interested in the NS records that a.root-servers.net had for the root zone.
The next line, (1 server found), tells us that when dig looked up the addresses associated with the domain name we specified after the "@," a.root-servers.net, it found one. (If dig finds more than three, the maximum number of name servers most resolvers can query, it'll report three.)
The line beginning with ->> HEADER <<- is the first part of the header of the reply message that dig received from the remote name server. The opcode in the header is always QUERY, just as it is with nslookup. The status is NOERROR; it can be any of the statuses mentioned earlier in this chapter. The ID is the message ID, a 16-bit number used to match responses to queries.
The flags tell us a bit more about the response. qr indicates that the message was a response, not a query. dig decodes responses, not queries, so qr will always be present. Not so with aa or rd, though. aa indicates that the response was authoritative, and rd indicates that the recursion desired bit was set in the query (since the responding name server just copies the bit from the query to the response). Most of the time rd is set in the query, you'll also see ra set in the response, indicating that recursion was available from the remote name server. However, a.root-servers.net is a root name server and has recursion disabled, so it handles recursive queries the same as it does iterative queries. So it ignores the rd bit and correctly indicates that recursion wasn't available by leaving ra unset.
The last fields in the header indicate that dig asked one question and received 13 records in the answer section, zero records in the authority section, and 13 records in the additional data section.
The line after the line that contains QUERY SECTION shows us the query dig sent: for the NS records in the IN class for the root zone. After ANSWER SECTION, we see the 13 NS records for the root name servers, and after ADDITIONAL SECTION, we have the 13 A records that correspond to those 13 root name servers. If the response had included an authority section, we'd have seen that, too, after AUTHORITY SECTION.
At the very end, dig includes summary information about the query and response. The first line shows you how long it took the remote name server to return the response after dig sent the query. The second line shows you from which host you sent the query and to which name server you sent it. The third line is a timestamp showing when the response was received. And the fourth line shows you the size of the query and the response, in bytes.
As with nslookup, you can use dig to initiate zone transfers. Unlike nslookup, though, dig has no special command to request a zone transfer. Instead, you simply specify axfr (as the query type) and the domain name of the zone as arguments. Remember that you can only transfer a zone from a name server that's authoritative for the zone.
So to transfer the movie.edu zone from wormhole.movie.edu, you could use:
C:\> dig @wormhole.movie.edu movie.edu axfr ; <<>> DiG 8.4 <<>> @wormhole.movie.edu movie.edu axfr ; (1 server found) $ORIGIN movie.edu. @ 1D IN SOA terminator al.robocop ( 2000091402 ; serial 3H ; refresh 1H ; retry 1W ; expiry 1H ) ; minimum 1D IN NS terminator 1D IN NS wormhole 1D IN NS outland.fx outland.fx 1D IN A 220.127.116.11 wormhole 1D IN A 18.104.22.168 1D IN A 22.214.171.124 wh249 1D IN A 126.96.36.199 robocop 1D IN A 188.8.131.52 bigt 1D IN CNAME terminator cujo 1D IN TXT "Location:" "machine" "room" "dog" "house" wh253 1D IN A 184.108.40.206 wh 1D IN CNAME wormhole shining 1D IN A 220.127.116.11 terminator 1D IN A 18.104.22.168 localhost 1D IN A 127.0.0.1 fx 1D IN NS bladerunner.fx bladerunner.fx 1D IN A 22.214.171.124 fx 1D IN NS outland.fx outland.fx 1D IN A 126.96.36.199 dh 1D IN CNAME diehard carrie 1D IN A 188.8.131.52 diehard 1D IN A 184.108.40.206 misery 1D IN A 220.127.116.11 @ 1D IN SOA terminator al.robocop ( 2000091402 ; serial 3H ; refresh 1H ; retry 1W ; expiry 1H ) ; minimum ;; Received 25 answers (25 records). ;; FROM: terminator.movie.edu to SERVER: wormhole.movie.edu ;; WHEN: Tue Aug 12 14:50:03 2003
Note that as with nslookup, the SOA record appears twice, at the beginning and the end of the zone.
There are too many dig command-line options to show here, so look at dig's manual page for an exhaustive list. Here's a list of the most important ones, though, and what they do:
nslookup is smart enough to recognize an IP address and look up the appropriate domain name in in-addr.arpa, so why not dig? If you use the -x option, dig assumes that the domain name argument you've specified is really an IP address, so it inverts the octets and tacks on in-addr.arpa. Using -x also changes the default record type looked up to ANY, so you can reverse map an IP address with dig -x 10.0.0.1.
Send queries to the specified port instead of port 53, the default.
Turn off recursion (recursion is on by default).
Send TCP-based queries (queries are UDP by default).