Skip to content

Commit c813bb1

Browse files
committed
doc: update explanation of DNS output [skip ci]
Structure the output explanation into a bulleted list, to make it easier for users to find the field they're interested in. - Rename the section titles to "DNS Requests" and "DNS Responses" because it was hard for me to tell that "TCP and UDP Name Server" were meant to refer to DNS. - Remove the "written in Greek" disclaimer and instead just make it more clear for folks who may not have read RFC 1035 - Use IP addresses instead of hostnames in the output examples, since that's the recommended way to use tcpdump Query section: - In "Other Anomalies", say that tcpdump will also print the hex value if "TC" is set in the query Response section: - Add a more complete description of how the flags are represented (including AA and AD, not just TC and RA). Verified by running some test DNS queries.
1 parent d356339 commit c813bb1

File tree

2 files changed

+269
-78
lines changed

2 files changed

+269
-78
lines changed

dns.md

Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
## DNS requests
2+
3+
DNS requests are formatted as:
4+
5+
> src > dst: id op? flags qtype qclass name (len)
6+
7+
For example, let's break down this line:
8+
9+
> 192.0.2.1.1234 > 8.8.8.8.53: 492+ [1au] A? example.com. (36)
10+
11+
The most commonly used fields here are:
12+
13+
* **Source IP and port**: \`192.0.2.1.1234'
14+
* **Destination IP and port**: \`8.8.8.8.53'
15+
* **DNS query type**: \`A'. The query type is right before the \`?'
16+
* **Domain name** being looked up: \`example.com.'
17+
18+
All the other fields, in the order they appear:
19+
20+
* **Query ID**: \`492'
21+
* **Opcode**: The opcode was the normal one, *Query*, so it was omitted.
22+
Any other opcode would have been printed between the \`492' and
23+
the \`+', for example \`492 update+'
24+
* **Flags**: \`+' means the "recursion desired" flag was set
25+
* **Records in the query**: \`[1au]' means that the query contains 1 record in the "additional" section. In general:
26+
* \`\[*n*a\]' means "*n* answer records"
27+
* \`\[*n*n\]' means "*n* authority records"
28+
* \`\[*n*au\]' means "*n* additional records"
29+
* **Class**: The query class was the normal one, *C_IN*, so it was omitted.
30+
Any other query class would have been printed immediately after the \`A'
31+
* **Other anomalies**: If any of the response bits are set (AA, RA, TC or response code)
32+
or any of the "must be zero" bits are set in bytes two and three,
33+
\`\[b2&3=*x*\]' is printed, where *x* is the hex value of header bytes
34+
two and three.
35+
* **Query length**: 36 bytes (excluding the TCP or UDP and IP protocol headers)
36+
37+
## DNS Responses
38+
39+
DNS responses are formatted as
40+
41+
> src > dst: id op rcode flags a/n/au type class data (len)
42+
43+
Here are 2 example responses we'll break down:
44+
45+
> #1: IP 8.8.8.8.53 > 192.0.2.1.1234: 492 2/0/1 A 104.18.27.120, A 104.18.26.120 (72)
46+
> #2: IP 8.8.8.8.53 > 192.0.2.1.1234: 492 NXDomain 0/0/1 (46)
47+
48+
The most commonly used fields here are:
49+
50+
* **Source IP and port**: `192.0.2.1.1234`
51+
* **Destination IP and port**: `8.8.8.8.53`
52+
* **The records**: In example 1, the server replied with two A records: \`A 104.18.27.120' and \`A 104.18.26.120'
53+
* **DNS response code**: In example 2, the response code is "NXDomain", which means the domain wasn't found
54+
55+
All the other fields, in the order they appear:
56+
57+
* **Query ID**: 492
58+
* **Opcode**: Same as for DNS requests above. Omitted here.
59+
* **Flags**: Flags are after the query ID and opcode (for example `492 update|`), and are encoded like this:
60+
* RA: '-' if RA is missing ("Recursion Available")
61+
* TC: '|' ("Truncated")
62+
* AA: '*' ("Authoritative Answer")
63+
* AD: '$' ("Authenticated Data")
64+
* **Question records**: If the \`question' section doesn't contain
65+
exactly one entry, \`\[*n*q\]' is printed.
66+
* **Total number of records**: `2/0/1`: This means 2 _answer records_, 0 _authority records_, and 1 _additional record_ (from example 1)
67+
* **Class**: Same as for DNS requests above. Omitted here.
68+
* **Length**: Same as for DNS requests above.

tcpdump.1.in

Lines changed: 201 additions & 78 deletions
Original file line numberDiff line numberDiff line change
@@ -1750,90 +1750,213 @@ Some UDP services are recognized (from the source or destination
17501750
port number) and the higher level protocol information printed.
17511751
In particular, Domain Name service requests (RFC 1034/1035) and Sun
17521752
RPC calls (RFC 1050) to NFS.
1753-
.SS TCP or UDP Name Server Requests
1753+
.SS
1754+
DNS requests
17541755
.LP
1755-
\fI(N.B.:The following description assumes familiarity with
1756-
the Domain Service protocol described in RFC 1035.
1757-
If you are not familiar
1758-
with the protocol, the following description will appear to be written
1759-
in Greek.)\fP
1756+
DNS requests are formatted as:
1757+
.RS
17601758
.LP
1761-
Name server requests are formatted as
1759+
.EX
1760+
src > dst: id op? flags qtype qclass name (len)
1761+
.EE
1762+
.RE
1763+
.PP
1764+
For example, let\(cqs break down this line:
17621765
.RS
1763-
.nf
1764-
.sp .5
1765-
\fIsrc > dst: id op? flags qtype qclass name (len)\fP
1766-
.sp .5
1767-
\f(CWh2opolo.1538 > helios.domain: 3+ A? ucbvax.berkeley.edu. (37)\fR
1768-
.sp .5
1769-
.fi
1766+
.LP
1767+
.EX
1768+
192.0.2.1.1234 > 8.8.8.8.53: 492+ [1au] A? example.com. (36)
1769+
.EE
17701770
.RE
1771-
Host \fIh2opolo\fP asked the domain server on \fIhelios\fP for an
1772-
address record (qtype=A) associated with the name \fIucbvax.berkeley.edu.\fP
1773-
The query id was `3'.
1774-
The `+' indicates the \fIrecursion desired\fP flag
1775-
was set.
1776-
The query length was 37 bytes, excluding the TCP or UDP and
1777-
IP protocol headers.
1778-
The query operation was the normal one, \fIQuery\fP,
1779-
so the op field was omitted.
1780-
If the op had been anything else, it would
1781-
have been printed between the `3' and the `+'.
1782-
Similarly, the qclass was the normal one,
1783-
.BR C_IN ,
1784-
and omitted.
1785-
Any other qclass would have been printed
1786-
immediately after the `A'.
1787-
.LP
1788-
A few anomalies are checked and may result in extra fields enclosed in
1789-
square brackets: If a query contains an answer, authority records or
1790-
additional records section,
1791-
.IR ancount ,
1792-
.IR nscount ,
1793-
or
1794-
.I arcount
1795-
are printed as `[\fIn\fPa]', `[\fIn\fPn]' or `[\fIn\fPau]' where \fIn\fP
1796-
is the appropriate count.
1797-
If any of the response bits are set (AA, RA or rcode) or any of the
1798-
`must be zero' bits are set in bytes two and three, `[b2&3=\fIx\fP]'
1799-
is printed, where \fIx\fP is the hex value of header bytes two and three.
1800-
.SS TCP or UDP Name Server Responses
1801-
.LP
1802-
Name server responses are formatted as
1771+
.PP
1772+
The most commonly used fields here are:
1773+
.IP "\(bu" 3
1774+
\fBSource IP and port\fR: \(ga192.0.2.1.1234\(cq
1775+
.if n \
1776+
.sp -1
1777+
.if t \
1778+
.sp -0.25v
1779+
.IP "\(bu" 3
1780+
\fBDestination IP and port\fR: \(ga8.8.8.8.53\(cq
1781+
.if n \
1782+
.sp -1
1783+
.if t \
1784+
.sp -0.25v
1785+
.IP "\(bu" 3
1786+
\fBDNS query type\fR: \(gaA\(cq. The query type is right before the \(ga?\(cq
1787+
.if n \
1788+
.sp -1
1789+
.if t \
1790+
.sp -0.25v
1791+
.IP "\(bu" 3
1792+
\fBDomain name\fR being looked up: \(gaexample.com.\(cq
1793+
.LP
1794+
All the other fields, in the order they appear:
1795+
.IP "\(bu" 3
1796+
\fBQuery ID\fR: \(ga492\(cq
1797+
.if n \
1798+
.sp -1
1799+
.if t \
1800+
.sp -0.25v
1801+
.IP "\(bu" 3
1802+
\fBOpcode\fR: The opcode was the normal one, \fIQuery\fR, so it was omitted.
1803+
Any other opcode would have been printed between the \(ga492\(cq and
1804+
the \(ga+\(cq, for example \(ga492 update+\(cq
1805+
.if n \
1806+
.sp -1
1807+
.if t \
1808+
.sp -0.25v
1809+
.IP "\(bu" 3
1810+
\fBFlags\fR: \f(CR+\fR means the \(lqrecursion desired\(rq flag was set
1811+
.if n \
1812+
.sp -1
1813+
.if t \
1814+
.sp -0.25v
1815+
.IP "\(bu" 3
1816+
\fBRecords in the query\fR: \(ga[1au]\(cq means that the query contains 1 record in the \(lqadditional\(rq section. In general:
18031817
.RS
1804-
.nf
1805-
.sp .5
1806-
\fIsrc > dst: id op rcode flags a/n/au type class data (len)\fP
1807-
.sp .5
1808-
\f(CWhelios.domain > h2opolo.1538: 3 3/3/7 A 128.32.137.3 (273)
1809-
helios.domain > h2opolo.1537: 2 NXDomain* 0/1/0 (97)\fR
1810-
.sp .5
1811-
.fi
1818+
.IP "\(bu" 3
1819+
\(ga[\fIn\fRa]\(cq means \(lq\fIn\fR answer records\(rq
1820+
.if n \
1821+
.sp -1
1822+
.if t \
1823+
.sp -0.25v
1824+
.IP "\(bu" 3
1825+
\(ga[\fIn\fRn]\(cq means \(lq\fIn\fR authority records\(rq
1826+
.if n \
1827+
.sp -1
1828+
.if t \
1829+
.sp -0.25v
1830+
.IP "\(bu" 3
1831+
\(ga[\fIn\fRau]\(cq means \(lq\fIn\fR additional records\(rq
18121832
.RE
1813-
In the first example, \fIhelios\fP responds to query id 3 from \fIh2opolo\fP
1814-
with 3 answer records, 3 name server records and 7 additional records.
1815-
The first answer record is type A (address) and its data is internet
1816-
address 128.32.137.3.
1817-
The total size of the response was 273 bytes,
1818-
excluding TCP or UDP and IP headers.
1819-
The op (Query) and response code
1820-
(NoError) were omitted, as was the class
1821-
.RB ( C_IN )
1822-
of the A record.
1823-
.LP
1824-
In the second example, \fIhelios\fP responds to query 2 with a
1825-
response code of nonexistent domain (NXDomain) with no answers,
1826-
one name server and no authority records.
1827-
The `*' indicates that
1828-
the \fIauthoritative answer\fP bit was set.
1829-
Since there were no
1830-
answers, no type, class or data were printed.
1831-
.LP
1832-
Other flag characters that might appear are `\-' (recursion available,
1833-
RA, \fInot\fP set) and `|' (truncated message, TC, set).
1834-
If the
1835-
`question' section doesn't contain exactly one entry, `[\fIn\fPq]'
1836-
is printed.
1833+
.if n \
1834+
.sp -1
1835+
.if t \
1836+
.sp -0.25v
1837+
.IP "\(bu" 3
1838+
\fBClass\fR: The query class was the normal one, \fIC_IN\fR, so it was omitted.
1839+
Any other query class would have been printed immediately after the \(gaA\(cq
1840+
.if n \
1841+
.sp -1
1842+
.if t \
1843+
.sp -0.25v
1844+
.IP "\(bu" 3
1845+
\fBOther anomalies\fR: If any of the response bits are set (AA, RA, TC or response code)
1846+
or any of the \(lqmust be zero\(rq bits are set in bytes two and three,
1847+
\(ga[b2&3=\fIx\fR]\(cq is printed, where \fIx\fR is the hex value of header bytes
1848+
two and three.
1849+
.if n \
1850+
.sp -1
1851+
.if t \
1852+
.sp -0.25v
1853+
.IP "\(bu" 3
1854+
\fBQuery length\fR: 36 bytes (excluding the TCP or UDP and IP protocol headers)
1855+
.SS
1856+
DNS Responses
1857+
.LP
1858+
DNS responses are formatted as
1859+
.RS
1860+
.LP
1861+
.EX
1862+
src > dst: id op rcode flags a/n/au type class data (len)
1863+
.EE
1864+
.RE
1865+
.PP
1866+
Here are 2 example responses we\(cqll break down:
1867+
.RS
1868+
.LP
1869+
.EX
1870+
#1: IP 8.8.8.8.53 > 192.0.2.1.1234: 492 2/0/1 A 104.18.27.120, A 104.18.26.120 (72)
1871+
#2: IP 8.8.8.8.53 > 192.0.2.1.1234: 492 NXDomain 0/0/1 (46)
1872+
.EE
1873+
.RE
1874+
.PP
1875+
The most commonly used fields here are:
1876+
.IP "\(bu" 3
1877+
\fBSource IP and port\fR: \f(CR192.0.2.1.1234\fR
1878+
.if n \
1879+
.sp -1
1880+
.if t \
1881+
.sp -0.25v
1882+
.IP "\(bu" 3
1883+
\fBDestination IP and port\fR: \f(CR8.8.8.8.53\fR
1884+
.if n \
1885+
.sp -1
1886+
.if t \
1887+
.sp -0.25v
1888+
.IP "\(bu" 3
1889+
\fBThe records\fR: In example 1, the server replied with two A records: \(gaA 104.18.27.120\(cq and \(gaA 104.18.26.120\(cq
1890+
.if n \
1891+
.sp -1
1892+
.if t \
1893+
.sp -0.25v
1894+
.IP "\(bu" 3
1895+
\fBDNS response code\fR: In example 2, the response code is \(lqNXDomain\(rq, which means the domain wasn\(cqt found
1896+
.LP
1897+
All the other fields, in the order they appear:
1898+
.IP "\(bu" 3
1899+
\fBQuery ID\fR: 492
1900+
.br
1901+
.if n \
1902+
.sp -1
1903+
.if t \
1904+
.sp -0.25v
1905+
.IP "\(bu" 3
1906+
\fBOpcode\fR: Same as for DNS requests above. Omitted here.
1907+
.if n \
1908+
.sp -1
1909+
.if t \
1910+
.sp -0.25v
1911+
.IP "\(bu" 3
1912+
\fBFlags\fR: Flags are after the query ID and opcode (for example \f(CR492 update|\fR), and are encoded like this:
1913+
.RS
1914+
.IP "\(bu" 3
1915+
RA: \(oq-\(cq if RA is missing (\(lqRecursion Available\(rq)
1916+
.if n \
1917+
.sp -1
1918+
.if t \
1919+
.sp -0.25v
1920+
.IP "\(bu" 3
1921+
TC: \(oq|\(cq (\(lqTruncated\(rq)
1922+
.if n \
1923+
.sp -1
1924+
.if t \
1925+
.sp -0.25v
1926+
.IP "\(bu" 3
1927+
AA: \(oq*\(cq (\(lqAuthoritative Answer\(rq)
1928+
.if n \
1929+
.sp -1
1930+
.if t \
1931+
.sp -0.25v
1932+
.IP "\(bu" 3
1933+
AD: \(oq$\(cq (\(lqAuthenticated Data\(rq)
1934+
.RE
1935+
.if n \
1936+
.sp -1
1937+
.if t \
1938+
.sp -0.25v
1939+
.IP "\(bu" 3
1940+
\fBQuestion records\fR: If the \(gaquestion\(cq section doesn\(cqt contain
1941+
exactly one entry, \(ga[\fIn\fRq]\(cq is printed.
1942+
.if n \
1943+
.sp -1
1944+
.if t \
1945+
.sp -0.25v
1946+
.IP "\(bu" 3
1947+
\fBTotal number of records\fR: \f(CR2/0/1\fR: This means 2 \fIanswer records\fR, 0 \fIauthority records\fR, and 1 \fIadditional record\fR (from example 1)
1948+
.if n \
1949+
.sp -1
1950+
.if t \
1951+
.sp -0.25v
1952+
.IP "\(bu" 3
1953+
\fBClass\fR: Same as for DNS requests above. Omitted here.
1954+
.if n \
1955+
.sp -1
1956+
.if t \
1957+
.sp -0.25v
1958+
.IP "\(bu" 3
1959+
\fBLength\fR: Same as for DNS requests above.
18371960
.SS SMB/CIFS Decoding
18381961
.LP
18391962
\fItcpdump\fP now includes fairly extensive SMB/CIFS/NBT decoding for data

0 commit comments

Comments
 (0)