[dns-operations] Utilities for showing DNS packets

Robert Edmonds edmonds at mycre.ws
Thu Mar 24 18:30:10 UTC 2016


Jim Reid wrote:
> > On 24 Mar 2016, at 00:32, Paul Hoffman <paul.hoffman at vpnc.org> wrote:
> > 
> > Greetings again. There are many ways to visually describe the contents of an DNS packet. Dig's output is a common one, but for an application I'm writing it is kind of wasteful of vertical space. Are there other utils (C or Python preferred, but other languages are fine) that people like? Ability to display messages with name compression (cough cough priming responses cough) is a big plus.

If your data is in pcap format, there are a number of tools that can
pretty print DNS messages contained in pcap files.

There's the dnscap utility (https://github.com/verisign/dnscap)
currently maintained by Duane Wessels, but I'm almost positive the
output formatter was originally written by Paul Vixie. Its output isn't
quite dig-like; I think it was designed to be easier to parse by
scripts, so it might not be what you're looking for. Its output looks
like this:

# ./dnscap -g -r ../../packets/testdns.pcap -c 2
[56] 2008-06-10 18:48:26.002226 [#0 ../../packets/testdns.pcap 4095] \
	[69.94.222.154].32975 [198.41.0.4].53  \
	dns QUERY,NOERROR,64443,cd \
	1 .,IN,NS 0 0 \
	1 .,4096,4096,32768,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=1,z=0] \
	,[0]
[643] 2008-06-10 18:48:26.026313 [#1 ../../packets/testdns.pcap 4095] \
	[198.41.0.4].53 [69.94.222.154].32975  \
	dns QUERY,NOERROR,64443,qr|aa|cd \
	1 .,IN,NS \
	13 .,IN,NS,518400,K.ROOT-SERVERS.NET \
	.,IN,NS,518400,L.ROOT-SERVERS.NET \
	.,IN,NS,518400,M.ROOT-SERVERS.NET \
	.,IN,NS,518400,A.ROOT-SERVERS.NET \
	.,IN,NS,518400,B.ROOT-SERVERS.NET \
	.,IN,NS,518400,C.ROOT-SERVERS.NET \
	.,IN,NS,518400,D.ROOT-SERVERS.NET \
	.,IN,NS,518400,E.ROOT-SERVERS.NET \
	.,IN,NS,518400,F.ROOT-SERVERS.NET \
	.,IN,NS,518400,G.ROOT-SERVERS.NET \
	.,IN,NS,518400,H.ROOT-SERVERS.NET \
	.,IN,NS,518400,I.ROOT-SERVERS.NET \
	.,IN,NS,518400,J.ROOT-SERVERS.NET 0 \
	20 A.ROOT-SERVERS.NET,IN,A,3600000,198.41.0.4 \
	A.ROOT-SERVERS.NET,IN,AAAA,3600000,2001:503:ba3e::2:30 \
	B.ROOT-SERVERS.NET,IN,A,3600000,192.228.79.201 \
	C.ROOT-SERVERS.NET,IN,A,3600000,192.33.4.12 \
	D.ROOT-SERVERS.NET,IN,A,3600000,128.8.10.90 \
	E.ROOT-SERVERS.NET,IN,A,3600000,192.203.230.10 \
	F.ROOT-SERVERS.NET,IN,A,3600000,192.5.5.241 \
	F.ROOT-SERVERS.NET,IN,AAAA,3600000,2001:500:2f::f \
	G.ROOT-SERVERS.NET,IN,A,3600000,192.112.36.4 \
	H.ROOT-SERVERS.NET,IN,A,3600000,128.63.2.53 \
	H.ROOT-SERVERS.NET,IN,AAAA,3600000,2001:500:1::803f:235 \
	I.ROOT-SERVERS.NET,IN,A,3600000,192.36.148.17 \
	J.ROOT-SERVERS.NET,IN,A,3600000,192.58.128.30 \
	J.ROOT-SERVERS.NET,IN,AAAA,3600000,2001:503:c27::2:30 \
	K.ROOT-SERVERS.NET,IN,A,3600000,193.0.14.129 \
	K.ROOT-SERVERS.NET,IN,AAAA,3600000,2001:7fd::1 \
	L.ROOT-SERVERS.NET,IN,A,3600000,199.7.83.42 \
	M.ROOT-SERVERS.NET,IN,A,3600000,202.12.27.33 \
	M.ROOT-SERVERS.NET,IN,AAAA,3600000,2001:dc3::35 \
	.,4096,4096,32768,edns0[len=0,UDP=4096,ver=0,rcode=0,DO=1,z=0] \
	,[0]

It's a little bit more compact than dig style, but not by much. It still
consumes one line for each RR. It uses the "libbind" or "libresolv" DNS
message parser which is typically included in the base system of most
Linux, BSD, etc. systems.

(Side note on dnscap: it looks like you currently have to run dnscap as
root(!) even when just reading a file because the privilege dropping
code exits the process if it fails to drop privileges, and dropping
privileges is a privileged operation.)

There's the golang 'dns' package maintained by Miek Gieben
(https://godoc.org/github.com/miekg/dns) which includes a full DNS
message parser and printer, but the Msg type's "String()" function is
described as producing "dig-like output".

I think Bob Halley's dnspython (http://www.dnspython.org/) has a message
printer, too.

> Hi Paul. For the gTLD name collision study in 2013 I used tcpdump to pretty-print the DNS packets in the DITL pcap files. [That was the only tool available to me at the time which could do this.] tcpdump prints out one line of text for each query and response. It doesn’t make a distinction between the data in the Answer, Authority and Additional Sections though. I suppose it would be a simple matter of programming to fix this.

In 2013 you could have also used a tool I wrote
(https://github.com/farsightsec/nmsg) which can pretty print DNS packets
from pcap files. Its output looks like this:

$ nmsgtool -T dnsqr -p testdns.pcap -c 1
[766] [2008-06-10 18:48:26.002226000] [1:9 base dnsqr] [00000000] [] [] 
type: UDP_QUERY_RESPONSE
query_ip: 69.94.222.154
response_ip: 198.41.0.4
proto: UDP (17)
query_port: 32975
response_port: 53
id: 64443
qname: .
qclass: IN (1)
qtype: NS (2)
rcode: NOERROR (0)
delay: 0.024087
udp_checksum: CORRECT
query: [28 octets]
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 64443
;; flags: cd; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 0

;; QUESTION SECTION:
;. IN NS

;; ANSWER SECTION:

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:
---
response: [615 octets]
;; ->>HEADER<<- opcode: QUERY, rcode: NOERROR, id: 64443
;; flags: qr aa cd; QUERY: 1, ANSWER: 13, AUTHORITY: 0, ADDITIONAL: 19

;; QUESTION SECTION:
;. IN NS

;; ANSWER SECTION:
. 518400 IN NS K.ROOT-SERVERS.NET.
. 518400 IN NS L.ROOT-SERVERS.NET.
. 518400 IN NS M.ROOT-SERVERS.NET.
. 518400 IN NS A.ROOT-SERVERS.NET.
. 518400 IN NS B.ROOT-SERVERS.NET.
. 518400 IN NS C.ROOT-SERVERS.NET.
. 518400 IN NS D.ROOT-SERVERS.NET.
. 518400 IN NS E.ROOT-SERVERS.NET.
. 518400 IN NS F.ROOT-SERVERS.NET.
. 518400 IN NS G.ROOT-SERVERS.NET.
. 518400 IN NS H.ROOT-SERVERS.NET.
. 518400 IN NS I.ROOT-SERVERS.NET.
. 518400 IN NS J.ROOT-SERVERS.NET.

;; AUTHORITY SECTION:

;; ADDITIONAL SECTION:
A.ROOT-SERVERS.NET. 3600000 IN A 198.41.0.4
A.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:ba3e::2:30
B.ROOT-SERVERS.NET. 3600000 IN A 192.228.79.201
C.ROOT-SERVERS.NET. 3600000 IN A 192.33.4.12
D.ROOT-SERVERS.NET. 3600000 IN A 128.8.10.90
E.ROOT-SERVERS.NET. 3600000 IN A 192.203.230.10
F.ROOT-SERVERS.NET. 3600000 IN A 192.5.5.241
F.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:2f::f
G.ROOT-SERVERS.NET. 3600000 IN A 192.112.36.4
H.ROOT-SERVERS.NET. 3600000 IN A 128.63.2.53
H.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:500:1::803f:235
I.ROOT-SERVERS.NET. 3600000 IN A 192.36.148.17
J.ROOT-SERVERS.NET. 3600000 IN A 192.58.128.30
J.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:503:c27::2:30
K.ROOT-SERVERS.NET. 3600000 IN A 193.0.14.129
K.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:7fd::1
L.ROOT-SERVERS.NET. 3600000 IN A 199.7.83.42
M.ROOT-SERVERS.NET. 3600000 IN A 202.12.27.33
M.ROOT-SERVERS.NET. 3600000 IN AAAA 2001:dc3::35
---

Its format is still very dig-like, so still not quite what Paul is
looking for.

There's also the tshark utility (from Wireshark), whose text format
looks like this:

$ tshark -r testdns.pcap -c 2
  1   0.000000 69.94.222.154 -> 198.41.0.4   DNS 70 Standard query 0xfbbb NS <Root> OPT
  2   0.024087   198.41.0.4 -> 69.94.222.154 DNS 657 Standard query response 0xfbbb NS <Root> NS K.ROOT-SERVERS.NET NS L.ROOT-SERVERS.NET NS M.ROOT-SERVERS.NET NS A.ROOT-SERVERS.NET NS B.ROOT-SERVERS.NET NS C.ROOT-SERVERS.NET NS D.ROOT-SERVERS.NET NS E.ROOT-SERVERS.NET NS F.ROOT-SERVERS.NET NS G.ROOT-SERVERS.NET NS H.ROOT-SERVERS.NET NS I.ROOT-SERVERS.NET NS J.ROOT-SERVERS.NET A 198.41.0.4 AAAA 2001:503:ba3e::2:30 A 192.228.79.201 A 192.33.4.12 A 128.8.10.90 A 192.203.230.10 A 192.5.5.241 AAAA 2001:500:2f::f A 192.112.36.4 A 128.63.2.53 AAAA 2001:500:1::803f:235 A 192.36.148.17 A 192.58.128.30 AAAA 2001:503:c27::2:30 A 193.0.14.129 AAAA 2001:7fd::1 A 199.7.83.42 A 202.12.27.33 AAAA 2001:dc3::35 OPT

> Roy Hooper of Demand Media later did pretty much the same thing using some perl scripts (I think) which are probably lying around on one of the OARC servers. I think his ASCII-fied versions of the DITL pcap data sets are still there too.

-- 
Robert Edmonds



More information about the dns-operations mailing list