Skip to content

Commit e2774d2

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 d39dc77 commit e2774d2

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

0 commit comments

Comments
 (0)