Domain Name Service Protocol


Unlike many of the other protocols in widespread use on the Internet, DNS is mainly a binary protocol, and also uses both UDP and TCP for data transmission. There is a single basic DNS message format for queries and answers (enjoy the ASCII-licious graphics):

0              15 16             31
+----------------+----------------+
| identification |     flags      |
+----------------+----------------+
|  # questions   |    # answers   |
+----------------+----------------+
|  # authority   |  # additional  |
+----------------+----------------+
|            questions            |
|              . . .              |
+---------------------------------+
|             answers             |
|              . . .              |
+---------------------------------+
|            authority            |
|              . . .              |
+---------------------------------+
|     additional information      |
|              . . .              |
+---------------------------------+

identification is a serial number typically generated by a client and returned by a server for answers relating to that query, allowing clients to match replies with queries.

flags has a number of one-bit flags relating to query options, as well as four-bit query opcode and rcode (return code) fields.

For each of the four subrecord types, there is the number of each kind of subrecord included in the packet. The remaining part of the packet contains subrecords grouped by type in the indicated order.

In general name strings are represented by a sequence of length-counted "labels", so "ilab.cs.uoregon.edu" would appear in a query or answer as:

+-----------------------------------------+
|4|i|l|a|b|2|c|s|7|u|o|r|e|g|o|n|3|e|d|u|0|
+-----------------------------------------+

Here an italicized digit represents a byte with that value rather than an ASCII character. A 0 terminates a name string. Allowed characters in label strings are the letters a-z (case is insignificant), digits 0-9, and the dash -. The maximum length of any label is 63 characters.

A query subrecord looks like this:

+---------------------------------+
|           query name            |
+----------------+----------------+
|   query type   |   query class  |
+----------------+----------------+

The "query class" is a numeric code for the type of resource being queried for and the "query type" is almost always the value "1" for Internet data (although other types can be defined and used locally).

The other three record types share a common "resource record" format:

+---------------------------------+
|           domain name           |
+----------------+----------------+
|      type      |      class     |
+----------------+----------------+
|          time-to-live           |
+----------------+----------------+
|  data length   | resource data  |
+----------------+                |
|                                 |
+---------------------------------+

"type" and "class" use the same values as "query type" and "query class" above. "time-to-live" is a value in seconds that suggests the maximum amount of time a caching server should retain the data in its cache before re-querying. The "resource data" and "data length" depend on the answer type; for example, a query for an IPv4 address returns a four-byte value.

Generally you aren't going to have to decode DNS messages yourself. A generally-available utility called dig can generate queries and dump the replies in a human-readable format similar to that used in DNS server configuration.

The DNS protocol and implementation are described in RFCs 1034 and 1035, although a number of minor changes and new resource record types have been introduced in the years since those were written.

Next ->


Steve VanDevender
Last modified: Tue Dec 6 14:42:45 PST 2005