diff --git a/dns/dnsmessage/message.go b/dns/dnsmessage/message.go
new file mode 100644
index 0000000..da43b0b
--- /dev/null
+++ b/dns/dnsmessage/message.go
@@ -0,0 +1,1418 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+// Package dnsmessage provides a mostly RFC 1035 compliant implementation of
+// DNS message packing and unpacking.
+//
+// This implementation is designed to minimize heap allocations and avoid
+// unnecessary packing and unpacking as much as possible.
+package dnsmessage
+
+import (
+	"errors"
+)
+
+// Packet formats
+
+// A Type is a type of DNS request and response.
+type Type uint16
+
+// A Class is a type of network.
+type Class uint16
+
+// An OpCode is a DNS operation code.
+type OpCode uint16
+
+// An RCode is a DNS response status code.
+type RCode uint16
+
+// Wire constants.
+const (
+	// ResourceHeader.Type and Question.Type
+	TypeA     Type = 1
+	TypeNS    Type = 2
+	TypeCNAME Type = 5
+	TypeSOA   Type = 6
+	TypePTR   Type = 12
+	TypeMX    Type = 15
+	TypeTXT   Type = 16
+	TypeAAAA  Type = 28
+	TypeSRV   Type = 33
+
+	// Question.Type
+	TypeWKS   Type = 11
+	TypeHINFO Type = 13
+	TypeMINFO Type = 14
+	TypeAXFR  Type = 252
+	TypeALL   Type = 255
+
+	// ResourceHeader.Class and Question.Class
+	ClassINET   Class = 1
+	ClassCSNET  Class = 2
+	ClassCHAOS  Class = 3
+	ClassHESIOD Class = 4
+
+	// Question.Class
+	ClassANY Class = 255
+
+	// Message.Rcode
+	RCodeSuccess        RCode = 0
+	RCodeFormatError    RCode = 1
+	RCodeServerFailure  RCode = 2
+	RCodeNameError      RCode = 3
+	RCodeNotImplemented RCode = 4
+	RCodeRefused        RCode = 5
+)
+
+var (
+	// ErrNotStarted indicates that the prerequisite information isn't
+	// available yet because the previous records haven't been appropriately
+	// parsed or skipped.
+	ErrNotStarted = errors.New("parsing of this type isn't available yet")
+
+	// ErrSectionDone indicated that all records in the section have been
+	// parsed.
+	ErrSectionDone = errors.New("parsing of this section has completed")
+
+	errBaseLen            = errors.New("insufficient data for base length type")
+	errCalcLen            = errors.New("insufficient data for calculated length type")
+	errReserved           = errors.New("segment prefix is reserved")
+	errTooManyPtr         = errors.New("too many pointers (>10)")
+	errInvalidPtr         = errors.New("invalid pointer")
+	errResourceLen        = errors.New("insufficient data for resource body length")
+	errSegTooLong         = errors.New("segment length too long")
+	errZeroSegLen         = errors.New("zero length segment")
+	errResTooLong         = errors.New("resource length too long")
+	errTooManyQuestions   = errors.New("too many Questions to pack (>65535)")
+	errTooManyAnswers     = errors.New("too many Answers to pack (>65535)")
+	errTooManyAuthorities = errors.New("too many Authorities to pack (>65535)")
+	errTooManyAdditionals = errors.New("too many Additionals to pack (>65535)")
+)
+
+type nestedError struct {
+	// s is the current level's error message.
+	s string
+
+	// err is the nested error.
+	err error
+}
+
+// nestedError implements error.Error.
+func (e *nestedError) Error() string {
+	return e.s + ": " + e.err.Error()
+}
+
+// Header is a representation of a DNS message header.
+type Header struct {
+	ID                 uint16
+	Response           bool
+	OpCode             OpCode
+	Authoritative      bool
+	Truncated          bool
+	RecursionDesired   bool
+	RecursionAvailable bool
+	RCode              RCode
+}
+
+func (m *Header) pack() (id uint16, bits uint16) {
+	id = m.ID
+	bits = uint16(m.OpCode)<<11 | uint16(m.RCode)
+	if m.RecursionAvailable {
+		bits |= headerBitRA
+	}
+	if m.RecursionDesired {
+		bits |= headerBitRD
+	}
+	if m.Truncated {
+		bits |= headerBitTC
+	}
+	if m.Authoritative {
+		bits |= headerBitAA
+	}
+	if m.Response {
+		bits |= headerBitQR
+	}
+	return
+}
+
+// Message is a representation of a DNS message.
+type Message struct {
+	Header
+	Questions   []Question
+	Answers     []Resource
+	Authorities []Resource
+	Additionals []Resource
+}
+
+type section uint8
+
+const (
+	sectionHeader section = iota
+	sectionQuestions
+	sectionAnswers
+	sectionAuthorities
+	sectionAdditionals
+	sectionDone
+
+	headerBitQR = 1 << 15 // query/response (response=1)
+	headerBitAA = 1 << 10 // authoritative
+	headerBitTC = 1 << 9  // truncated
+	headerBitRD = 1 << 8  // recursion desired
+	headerBitRA = 1 << 7  // recursion available
+)
+
+var sectionNames = map[section]string{
+	sectionHeader:      "header",
+	sectionQuestions:   "Question",
+	sectionAnswers:     "Answer",
+	sectionAuthorities: "Authority",
+	sectionAdditionals: "Additional",
+}
+
+// header is the wire format for a DNS message header.
+type header struct {
+	id          uint16
+	bits        uint16
+	questions   uint16
+	answers     uint16
+	authorities uint16
+	additionals uint16
+}
+
+func (h *header) count(sec section) uint16 {
+	switch sec {
+	case sectionQuestions:
+		return h.questions
+	case sectionAnswers:
+		return h.answers
+	case sectionAuthorities:
+		return h.authorities
+	case sectionAdditionals:
+		return h.additionals
+	}
+	return 0
+}
+
+func (h *header) pack(msg []byte) []byte {
+	msg = packUint16(msg, h.id)
+	msg = packUint16(msg, h.bits)
+	msg = packUint16(msg, h.questions)
+	msg = packUint16(msg, h.answers)
+	msg = packUint16(msg, h.authorities)
+	return packUint16(msg, h.additionals)
+}
+
+func (h *header) unpack(msg []byte, off int) (int, error) {
+	newOff := off
+	var err error
+	if h.id, newOff, err = unpackUint16(msg, newOff); err != nil {
+		return off, &nestedError{"id", err}
+	}
+	if h.bits, newOff, err = unpackUint16(msg, newOff); err != nil {
+		return off, &nestedError{"bits", err}
+	}
+	if h.questions, newOff, err = unpackUint16(msg, newOff); err != nil {
+		return off, &nestedError{"questions", err}
+	}
+	if h.answers, newOff, err = unpackUint16(msg, newOff); err != nil {
+		return off, &nestedError{"answers", err}
+	}
+	if h.authorities, newOff, err = unpackUint16(msg, newOff); err != nil {
+		return off, &nestedError{"authorities", err}
+	}
+	if h.additionals, newOff, err = unpackUint16(msg, newOff); err != nil {
+		return off, &nestedError{"additionals", err}
+	}
+	return newOff, nil
+}
+
+func (h *header) header() Header {
+	return Header{
+		ID:                 h.id,
+		Response:           (h.bits & headerBitQR) != 0,
+		OpCode:             OpCode(h.bits>>11) & 0xF,
+		Authoritative:      (h.bits & headerBitAA) != 0,
+		Truncated:          (h.bits & headerBitTC) != 0,
+		RecursionDesired:   (h.bits & headerBitRD) != 0,
+		RecursionAvailable: (h.bits & headerBitRA) != 0,
+		RCode:              RCode(h.bits & 0xF),
+	}
+}
+
+// A Resource is a DNS resource record.
+type Resource interface {
+	// Header return's the Resource's ResourceHeader.
+	Header() *ResourceHeader
+
+	// pack packs a Resource except for its header.
+	pack(msg []byte, compression map[string]int) ([]byte, error)
+
+	// realType returns the actual type of the Resource. This is used to
+	// fill in the header Type field.
+	realType() Type
+}
+
+func packResource(msg []byte, resource Resource, compression map[string]int) ([]byte, error) {
+	oldMsg := msg
+	resource.Header().Type = resource.realType()
+	msg, length, err := resource.Header().pack(msg, compression)
+	if err != nil {
+		return msg, &nestedError{"ResourceHeader", err}
+	}
+	preLen := len(msg)
+	msg, err = resource.pack(msg, compression)
+	if err != nil {
+		return msg, &nestedError{"content", err}
+	}
+	conLen := len(msg) - preLen
+	if conLen > int(^uint16(0)) {
+		return oldMsg, errResTooLong
+	}
+	// Fill in the length now that we know how long the content is.
+	packUint16(length[:0], uint16(conLen))
+	resource.Header().Length = uint16(conLen)
+	return msg, nil
+}
+
+// A Parser allows incrementally parsing a DNS message.
+//
+// When parsing is started, the Header is parsed. Next, each Question can be
+// either parsed or skipped. Alternatively, all Questions can be skipped at
+// once. When all Questions have been parsed, attempting to parse Questions
+// will return (nil, nil) and attempting to skip Questions will return
+// (true, nil). After all Questions have been either parsed or skipped, all
+// Answers, Authorities and Additionals can be either parsed or skipped in the
+// same way, and each type of Resource must be fully parsed or skipped before
+// proceeding to the next type of Resource.
+//
+// Note that there is no requirement to fully skip or parse the message.
+type Parser struct {
+	msg    []byte
+	header header
+
+	section        section
+	off            int
+	index          int
+	resHeaderValid bool
+	resHeader      ResourceHeader
+}
+
+// Start parses the header and enables the parsing of Questions.
+func (p *Parser) Start(msg []byte) (Header, error) {
+	if p.msg != nil {
+		*p = Parser{}
+	}
+	p.msg = msg
+	var err error
+	if p.off, err = p.header.unpack(msg, 0); err != nil {
+		return Header{}, &nestedError{"unpacking header", err}
+	}
+	p.section = sectionQuestions
+	return p.header.header(), nil
+}
+
+func (p *Parser) checkAdvance(sec section) error {
+	if p.section < sec {
+		return ErrNotStarted
+	}
+	if p.section > sec {
+		return ErrSectionDone
+	}
+	p.resHeaderValid = false
+	if p.index == int(p.header.count(sec)) {
+		p.index = 0
+		p.section++
+		return ErrSectionDone
+	}
+	return nil
+}
+
+func (p *Parser) resource(sec section) (Resource, error) {
+	var r Resource
+	hdr, err := p.resourceHeader(sec)
+	if err != nil {
+		return r, err
+	}
+	p.resHeaderValid = false
+	r, p.off, err = unpackResource(p.msg, p.off, hdr)
+	if err != nil {
+		return nil, &nestedError{"unpacking " + sectionNames[sec], err}
+	}
+	p.index++
+	return r, nil
+}
+
+func (p *Parser) resourceHeader(sec section) (ResourceHeader, error) {
+	if p.resHeaderValid {
+		return p.resHeader, nil
+	}
+	if err := p.checkAdvance(sec); err != nil {
+		return ResourceHeader{}, err
+	}
+	var hdr ResourceHeader
+	off, err := hdr.unpack(p.msg, p.off)
+	if err != nil {
+		return ResourceHeader{}, err
+	}
+	p.resHeaderValid = true
+	p.resHeader = hdr
+	p.off = off
+	return hdr, nil
+}
+
+func (p *Parser) skipResource(sec section) error {
+	if p.resHeaderValid {
+		newOff := p.off + int(p.resHeader.Length)
+		if newOff > len(p.msg) {
+			return errResourceLen
+		}
+		p.off = newOff
+		p.resHeaderValid = false
+		p.index++
+		return nil
+	}
+	if err := p.checkAdvance(sec); err != nil {
+		return err
+	}
+	var err error
+	p.off, err = skipResource(p.msg, p.off)
+	if err != nil {
+		return &nestedError{"skipping: " + sectionNames[sec], err}
+	}
+	p.index++
+	return nil
+}
+
+// Question parses a single Question.
+func (p *Parser) Question() (Question, error) {
+	if err := p.checkAdvance(sectionQuestions); err != nil {
+		return Question{}, err
+	}
+	name, off, err := unpackName(p.msg, p.off)
+	if err != nil {
+		return Question{}, &nestedError{"unpacking Question.Name", err}
+	}
+	typ, off, err := unpackType(p.msg, off)
+	if err != nil {
+		return Question{}, &nestedError{"unpacking Question.Type", err}
+	}
+	class, off, err := unpackClass(p.msg, off)
+	if err != nil {
+		return Question{}, &nestedError{"unpacking Question.Class", err}
+	}
+	p.off = off
+	p.index++
+	return Question{name, typ, class}, nil
+}
+
+// AllQuestions parses all Questions.
+func (p *Parser) AllQuestions() ([]Question, error) {
+	qs := make([]Question, 0, p.header.questions)
+	for {
+		q, err := p.Question()
+		if err == ErrSectionDone {
+			return qs, nil
+		}
+		if err != nil {
+			return nil, err
+		}
+		qs = append(qs, q)
+	}
+}
+
+// SkipQuestion skips a single Question.
+func (p *Parser) SkipQuestion() error {
+	if err := p.checkAdvance(sectionQuestions); err != nil {
+		return err
+	}
+	off, err := skipName(p.msg, p.off)
+	if err != nil {
+		return &nestedError{"skipping Question Name", err}
+	}
+	if off, err = skipType(p.msg, off); err != nil {
+		return &nestedError{"skipping Question Type", err}
+	}
+	if off, err = skipClass(p.msg, off); err != nil {
+		return &nestedError{"skipping Question Class", err}
+	}
+	p.off = off
+	p.index++
+	return nil
+}
+
+// SkipAllQuestions skips all Questions.
+func (p *Parser) SkipAllQuestions() error {
+	for {
+		if err := p.SkipQuestion(); err == ErrSectionDone {
+			return nil
+		} else if err != nil {
+			return err
+		}
+	}
+}
+
+// AnswerHeader parses a single Answer ResourceHeader.
+func (p *Parser) AnswerHeader() (ResourceHeader, error) {
+	return p.resourceHeader(sectionAnswers)
+}
+
+// Answer parses a single Answer Resource.
+func (p *Parser) Answer() (Resource, error) {
+	return p.resource(sectionAnswers)
+}
+
+// AllAnswers parses all Answer Resources.
+func (p *Parser) AllAnswers() ([]Resource, error) {
+	as := make([]Resource, 0, p.header.answers)
+	for {
+		a, err := p.Answer()
+		if err == ErrSectionDone {
+			return as, nil
+		}
+		if err != nil {
+			return nil, err
+		}
+		as = append(as, a)
+	}
+}
+
+// SkipAnswer skips a single Answer Resource.
+func (p *Parser) SkipAnswer() error {
+	return p.skipResource(sectionAnswers)
+}
+
+// SkipAllAnswers skips all Answer Resources.
+func (p *Parser) SkipAllAnswers() error {
+	for {
+		if err := p.SkipAnswer(); err == ErrSectionDone {
+			return nil
+		} else if err != nil {
+			return err
+		}
+	}
+}
+
+// AuthorityHeader parses a single Authority ResourceHeader.
+func (p *Parser) AuthorityHeader() (ResourceHeader, error) {
+	return p.resourceHeader(sectionAuthorities)
+}
+
+// Authority parses a single Authority Resource.
+func (p *Parser) Authority() (Resource, error) {
+	return p.resource(sectionAuthorities)
+}
+
+// AllAuthorities parses all Authority Resources.
+func (p *Parser) AllAuthorities() ([]Resource, error) {
+	as := make([]Resource, 0, p.header.authorities)
+	for {
+		a, err := p.Authority()
+		if err == ErrSectionDone {
+			return as, nil
+		}
+		if err != nil {
+			return nil, err
+		}
+		as = append(as, a)
+	}
+}
+
+// SkipAuthority skips a single Authority Resource.
+func (p *Parser) SkipAuthority() error {
+	return p.skipResource(sectionAuthorities)
+}
+
+// SkipAllAuthorities skips all Authority Resources.
+func (p *Parser) SkipAllAuthorities() error {
+	for {
+		if err := p.SkipAuthority(); err == ErrSectionDone {
+			return nil
+		} else if err != nil {
+			return err
+		}
+	}
+}
+
+// AdditionalHeader parses a single Additional ResourceHeader.
+func (p *Parser) AdditionalHeader() (ResourceHeader, error) {
+	return p.resourceHeader(sectionAdditionals)
+}
+
+// Additional parses a single Additional Resource.
+func (p *Parser) Additional() (Resource, error) {
+	return p.resource(sectionAdditionals)
+}
+
+// AllAdditionals parses all Additional Resources.
+func (p *Parser) AllAdditionals() ([]Resource, error) {
+	as := make([]Resource, 0, p.header.additionals)
+	for {
+		a, err := p.Additional()
+		if err == ErrSectionDone {
+			return as, nil
+		}
+		if err != nil {
+			return nil, err
+		}
+		as = append(as, a)
+	}
+}
+
+// SkipAdditional skips a single Additional Resource.
+func (p *Parser) SkipAdditional() error {
+	return p.skipResource(sectionAdditionals)
+}
+
+// SkipAllAdditionals skips all Additional Resources.
+func (p *Parser) SkipAllAdditionals() error {
+	for {
+		if err := p.SkipAdditional(); err == ErrSectionDone {
+			return nil
+		} else if err != nil {
+			return err
+		}
+	}
+}
+
+// Unpack parses a full Message.
+func (m *Message) Unpack(msg []byte) error {
+	var p Parser
+	var err error
+	if m.Header, err = p.Start(msg); err != nil {
+		return err
+	}
+	if m.Questions, err = p.AllQuestions(); err != nil {
+		return err
+	}
+	if m.Answers, err = p.AllAnswers(); err != nil {
+		return err
+	}
+	if m.Authorities, err = p.AllAuthorities(); err != nil {
+		return err
+	}
+	if m.Additionals, err = p.AllAdditionals(); err != nil {
+		return err
+	}
+	return nil
+}
+
+// Pack packs a full Message.
+func (m *Message) Pack() ([]byte, error) {
+	// Validate the lengths. It is very unlikely that anyone will try to
+	// pack more than 65535 of any particular type, but it is possible and
+	// we should fail gracefully.
+	if len(m.Questions) > int(^uint16(0)) {
+		return nil, errTooManyQuestions
+	}
+	if len(m.Answers) > int(^uint16(0)) {
+		return nil, errTooManyAnswers
+	}
+	if len(m.Authorities) > int(^uint16(0)) {
+		return nil, errTooManyAuthorities
+	}
+	if len(m.Additionals) > int(^uint16(0)) {
+		return nil, errTooManyAdditionals
+	}
+
+	var h header
+	h.id, h.bits = m.Header.pack()
+
+	h.questions = uint16(len(m.Questions))
+	h.answers = uint16(len(m.Answers))
+	h.authorities = uint16(len(m.Authorities))
+	h.additionals = uint16(len(m.Additionals))
+
+	// The starting capacity doesn't matter too much, but most DNS responses
+	// Will be <= 512 bytes as it is the limit for DNS over UDP.
+	msg := make([]byte, 0, 512)
+
+	msg = h.pack(msg)
+
+	// RFC 1035 allows (but does not require) compression for packing. RFC
+	// 1035 requires unpacking implementations to support compression, so
+	// unconditionally enabling it is fine.
+	//
+	// DNS lookups are typically done over UDP, and RFC 1035 states that UDP
+	// DNS packets can be a maximum of 512 bytes long. Without compression,
+	// many DNS response packets are over this limit, so enabling
+	// compression will help ensure compliance.
+	compression := map[string]int{}
+
+	for _, q := range m.Questions {
+		var err error
+		msg, err = q.pack(msg, compression)
+		if err != nil {
+			return nil, &nestedError{"packing Question", err}
+		}
+	}
+	for _, a := range m.Answers {
+		var err error
+		msg, err = packResource(msg, a, compression)
+		if err != nil {
+			return nil, &nestedError{"packing Answer", err}
+		}
+	}
+	for _, a := range m.Authorities {
+		var err error
+		msg, err = packResource(msg, a, compression)
+		if err != nil {
+			return nil, &nestedError{"packing Authority", err}
+		}
+	}
+	for _, a := range m.Additionals {
+		var err error
+		msg, err = packResource(msg, a, compression)
+		if err != nil {
+			return nil, &nestedError{"packing Additional", err}
+		}
+	}
+
+	return msg, nil
+}
+
+// An ResourceHeader is the header of a DNS resource record. There are
+// many types of DNS resource records, but they all share the same header.
+type ResourceHeader struct {
+	// Name is the domain name for which this resource record pertains.
+	Name string
+
+	// Type is the type of DNS resource record.
+	//
+	// This field will be set automatically during packing.
+	Type Type
+
+	// Class is the class of network to which this DNS resource record
+	// pertains.
+	Class Class
+
+	// TTL is the length of time (measured in seconds) which this resource
+	// record is valid for (time to live). All Resources in a set should
+	// have the same TTL (RFC 2181 Section 5.2).
+	TTL uint32
+
+	// Length is the length of data in the resource record after the header.
+	//
+	// This field will be set automatically during packing.
+	Length uint16
+}
+
+// Header implements Resource.Header.
+func (h *ResourceHeader) Header() *ResourceHeader {
+	return h
+}
+
+// pack packs all of the fields in a ResourceHeader except for the length. The
+// length bytes are returned as a slice so they can be filled in after the rest
+// of the Resource has been packed.
+func (h *ResourceHeader) pack(oldMsg []byte, compression map[string]int) (msg []byte, length []byte, err error) {
+	msg = oldMsg
+	if msg, err = packName(msg, h.Name, compression); err != nil {
+		return oldMsg, nil, &nestedError{"Name", err}
+	}
+	msg = packType(msg, h.Type)
+	msg = packClass(msg, h.Class)
+	msg = packUint32(msg, h.TTL)
+	lenBegin := len(msg)
+	msg = packUint16(msg, h.Length)
+	return msg, msg[lenBegin:], nil
+}
+
+func (h *ResourceHeader) unpack(msg []byte, off int) (int, error) {
+	newOff := off
+	var err error
+	if h.Name, newOff, err = unpackName(msg, newOff); err != nil {
+		return off, &nestedError{"Name", err}
+	}
+	if h.Type, newOff, err = unpackType(msg, newOff); err != nil {
+		return off, &nestedError{"Type", err}
+	}
+	if h.Class, newOff, err = unpackClass(msg, newOff); err != nil {
+		return off, &nestedError{"Class", err}
+	}
+	if h.TTL, newOff, err = unpackUint32(msg, newOff); err != nil {
+		return off, &nestedError{"TTL", err}
+	}
+	if h.Length, newOff, err = unpackUint16(msg, newOff); err != nil {
+		return off, &nestedError{"Length", err}
+	}
+	return newOff, nil
+}
+
+func skipResource(msg []byte, off int) (int, error) {
+	newOff, err := skipName(msg, off)
+	if err != nil {
+		return off, &nestedError{"Name", err}
+	}
+	if newOff, err = skipType(msg, newOff); err != nil {
+		return off, &nestedError{"Type", err}
+	}
+	if newOff, err = skipClass(msg, newOff); err != nil {
+		return off, &nestedError{"Class", err}
+	}
+	if newOff, err = skipUint32(msg, newOff); err != nil {
+		return off, &nestedError{"TTL", err}
+	}
+	length, newOff, err := unpackUint16(msg, newOff)
+	if err != nil {
+		return off, &nestedError{"Length", err}
+	}
+	if newOff += int(length); newOff > len(msg) {
+		return off, errResourceLen
+	}
+	return newOff, nil
+}
+
+func packUint16(msg []byte, field uint16) []byte {
+	return append(msg, byte(field>>8), byte(field))
+}
+
+func unpackUint16(msg []byte, off int) (uint16, int, error) {
+	if off+2 > len(msg) {
+		return 0, off, errBaseLen
+	}
+	return uint16(msg[off])<<8 | uint16(msg[off+1]), off + 2, nil
+}
+
+func skipUint16(msg []byte, off int) (int, error) {
+	if off+2 > len(msg) {
+		return off, errBaseLen
+	}
+	return off + 2, nil
+}
+
+func packType(msg []byte, field Type) []byte {
+	return packUint16(msg, uint16(field))
+}
+
+func unpackType(msg []byte, off int) (Type, int, error) {
+	t, o, err := unpackUint16(msg, off)
+	return Type(t), o, err
+}
+
+func skipType(msg []byte, off int) (int, error) {
+	return skipUint16(msg, off)
+}
+
+func packClass(msg []byte, field Class) []byte {
+	return packUint16(msg, uint16(field))
+}
+
+func unpackClass(msg []byte, off int) (Class, int, error) {
+	c, o, err := unpackUint16(msg, off)
+	return Class(c), o, err
+}
+
+func skipClass(msg []byte, off int) (int, error) {
+	return skipUint16(msg, off)
+}
+
+func packUint32(msg []byte, field uint32) []byte {
+	return append(
+		msg,
+		byte(field>>24),
+		byte(field>>16),
+		byte(field>>8),
+		byte(field),
+	)
+}
+
+func unpackUint32(msg []byte, off int) (uint32, int, error) {
+	if off+4 > len(msg) {
+		return 0, off, errBaseLen
+	}
+	v := uint32(msg[off])<<24 | uint32(msg[off+1])<<16 | uint32(msg[off+2])<<8 | uint32(msg[off+3])
+	return v, off + 4, nil
+}
+
+func skipUint32(msg []byte, off int) (int, error) {
+	if off+4 > len(msg) {
+		return off, errBaseLen
+	}
+	return off + 4, nil
+}
+
+func packText(msg []byte, field string) []byte {
+	for len(field) > 0 {
+		l := len(field)
+		if l > 255 {
+			l = 255
+		}
+		msg = append(msg, byte(l))
+		msg = append(msg, field[:l]...)
+		field = field[l:]
+	}
+	return msg
+}
+
+func unpackText(msg []byte, off int) (string, int, error) {
+	if off >= len(msg) {
+		return "", off, errBaseLen
+	}
+	beginOff := off + 1
+	endOff := beginOff + int(msg[off])
+	if endOff > len(msg) {
+		return "", off, errCalcLen
+	}
+	return string(msg[beginOff:endOff]), endOff, nil
+}
+
+func skipText(msg []byte, off int) (int, error) {
+	if off >= len(msg) {
+		return off, errBaseLen
+	}
+	endOff := off + 1 + int(msg[off])
+	if endOff > len(msg) {
+		return off, errCalcLen
+	}
+	return endOff, nil
+}
+
+func packBytes(msg []byte, field []byte) []byte {
+	return append(msg, field...)
+}
+
+func unpackBytes(msg []byte, off int, field []byte) (int, error) {
+	newOff := off + len(field)
+	if newOff > len(msg) {
+		return off, errBaseLen
+	}
+	copy(field, msg[off:newOff])
+	return newOff, nil
+}
+
+func skipBytes(msg []byte, off int, field []byte) (int, error) {
+	newOff := off + len(field)
+	if newOff > len(msg) {
+		return off, errBaseLen
+	}
+	return newOff, nil
+}
+
+// packName packs a domain name.
+//
+// Domain names are a sequence of counted strings split at the dots. They end
+// with a zero-length string. Compression can be used to reuse domain suffixes.
+//
+// The compression map will be updated with new domain suffixes. If compression
+// is nil, compression will not be used.
+func packName(msg []byte, name string, compression map[string]int) ([]byte, error) {
+	oldMsg := msg
+
+	// Add a trailing dot to canonicalize name.
+	if n := len(name); n == 0 || name[n-1] != '.' {
+		name += "."
+	}
+
+	// Allow root domain.
+	if name == "." {
+		return append(msg, 0), nil
+	}
+
+	// Emit sequence of counted strings, chopping at dots.
+	for i, begin := 0, 0; i < len(name); i++ {
+		// Check for the end of the segment.
+		if name[i] == '.' {
+			// The two most significant bits have special meaning.
+			// It isn't allowed for segments to be long enough to
+			// need them.
+			if i-begin >= 1<<6 {
+				return oldMsg, errSegTooLong
+			}
+
+			// Segments must have a non-zero length.
+			if i-begin == 0 {
+				return oldMsg, errZeroSegLen
+			}
+
+			msg = append(msg, byte(i-begin))
+
+			for j := begin; j < i; j++ {
+				msg = append(msg, name[j])
+			}
+
+			begin = i + 1
+			continue
+		}
+
+		// We can only compress domain suffixes starting with a new
+		// segment. A pointer is two bytes with the two most significant
+		// bits set to 1 to indicate that it is a pointer.
+		if (i == 0 || name[i-1] == '.') && compression != nil {
+			if ptr, ok := compression[name[i:]]; ok {
+				// Hit. Emit a pointer instead of the rest of
+				// the domain.
+				return append(msg, byte(ptr>>8|0xC0), byte(ptr)), nil
+			}
+
+			// Miss. Add the suffix to the compression table if the
+			// offset can be stored in the available 14 bytes.
+			if len(msg) <= int(^uint16(0)>>2) {
+				compression[name[i:]] = len(msg)
+			}
+		}
+	}
+	return append(msg, 0), nil
+}
+
+// unpackName unpacks a domain name.
+func unpackName(msg []byte, off int) (string, int, error) {
+	// currOff is the current working offset.
+	currOff := off
+
+	// newOff is the offset where the next record will start. Pointers lead
+	// to data that belongs to other names and thus doesn't count towards to
+	// the usage of this name.
+	newOff := off
+
+	// name is the domain name being unpacked.
+	name := make([]byte, 0, 255)
+
+	// ptr is the number of pointers followed.
+	var ptr int
+Loop:
+	for {
+		if currOff >= len(msg) {
+			return "", off, errBaseLen
+		}
+		c := int(msg[currOff])
+		currOff++
+		switch c & 0xC0 {
+		case 0x00: // String segment
+			if c == 0x00 {
+				// A zero length signals the end of the name.
+				break Loop
+			}
+			endOff := currOff + c
+			if endOff > len(msg) {
+				return "", off, errCalcLen
+			}
+			name = append(name, msg[currOff:endOff]...)
+			name = append(name, '.')
+			currOff = endOff
+		case 0xC0: // Pointer
+			if currOff >= len(msg) {
+				return "", off, errInvalidPtr
+			}
+			c1 := msg[currOff]
+			currOff++
+			if ptr == 0 {
+				newOff = currOff
+			}
+			// Don't follow too many pointers, maybe there's a loop.
+			if ptr++; ptr > 10 {
+				return "", off, errTooManyPtr
+			}
+			currOff = (c^0xC0)<<8 | int(c1)
+		default:
+			// Prefixes 0x80 and 0x40 are reserved.
+			return "", off, errReserved
+		}
+	}
+	if len(name) == 0 {
+		name = append(name, '.')
+	}
+	if ptr == 0 {
+		newOff = currOff
+	}
+	return string(name), newOff, nil
+}
+
+func skipName(msg []byte, off int) (int, error) {
+	// newOff is the offset where the next record will start. Pointers lead
+	// to data that belongs to other names and thus doesn't count towards to
+	// the usage of this name.
+	newOff := off
+
+Loop:
+	for {
+		if newOff >= len(msg) {
+			return off, errBaseLen
+		}
+		c := int(msg[newOff])
+		newOff++
+		switch c & 0xC0 {
+		case 0x00:
+			if c == 0x00 {
+				// A zero length signals the end of the name.
+				break Loop
+			}
+			// literal string
+			newOff += c
+			if newOff > len(msg) {
+				return off, errCalcLen
+			}
+		case 0xC0:
+			// Pointer to somewhere else in msg.
+
+			// Pointers are two bytes.
+			newOff++
+
+			// Don't follow the pointer as the data here has ended.
+			break Loop
+		default:
+			// Prefixes 0x80 and 0x40 are reserved.
+			return off, errReserved
+		}
+	}
+
+	return newOff, nil
+}
+
+// A Question is a DNS query.
+type Question struct {
+	Name  string
+	Type  Type
+	Class Class
+}
+
+func (q *Question) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	msg, err := packName(msg, q.Name, compression)
+	if err != nil {
+		return msg, &nestedError{"Name", err}
+	}
+	msg = packType(msg, q.Type)
+	return packClass(msg, q.Class), nil
+}
+
+func unpackResource(msg []byte, off int, hdr ResourceHeader) (Resource, int, error) {
+	var (
+		r    Resource
+		err  error
+		name string
+	)
+	switch hdr.Type {
+	case TypeA:
+		r, err = unpackAResource(hdr, msg, off)
+		name = "A"
+	case TypeNS:
+		r, err = unpackNSResource(hdr, msg, off)
+		name = "NS"
+	case TypeCNAME:
+		r, err = unpackCNAMEResource(hdr, msg, off)
+		name = "CNAME"
+	case TypeSOA:
+		r, err = unpackSOAResource(hdr, msg, off)
+		name = "SOA"
+	case TypePTR:
+		r, err = unpackPTRResource(hdr, msg, off)
+		name = "PTR"
+	case TypeMX:
+		r, err = unpackMXResource(hdr, msg, off)
+		name = "MX"
+	case TypeTXT:
+		r, err = unpackTXTResource(hdr, msg, off)
+		name = "TXT"
+	case TypeAAAA:
+		r, err = unpackAAAAResource(hdr, msg, off)
+		name = "AAAA"
+	case TypeSRV:
+		r, err = unpackSRVResource(hdr, msg, off)
+		name = "SRV"
+	}
+	if err != nil {
+		return nil, off, &nestedError{name + " record", err}
+	}
+	if r != nil {
+		return r, off + int(hdr.Length), nil
+	}
+	return nil, off, errors.New("invalid resource type: " + string(hdr.Type+'0'))
+}
+
+// A CNAMEResource is a CNAME Resource record.
+type CNAMEResource struct {
+	ResourceHeader
+
+	CNAME string
+}
+
+func (r *CNAMEResource) realType() Type {
+	return TypeCNAME
+}
+
+func (r *CNAMEResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	return packName(msg, r.CNAME, compression)
+}
+
+func unpackCNAMEResource(hdr ResourceHeader, msg []byte, off int) (*CNAMEResource, error) {
+	cname, _, err := unpackName(msg, off)
+	if err != nil {
+		return nil, err
+	}
+	return &CNAMEResource{hdr, cname}, nil
+}
+
+// An MXResource is an MX Resource record.
+type MXResource struct {
+	ResourceHeader
+
+	Pref uint16
+	MX   string
+}
+
+func (r *MXResource) realType() Type {
+	return TypeMX
+}
+
+func (r *MXResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	oldMsg := msg
+	msg = packUint16(msg, r.Pref)
+	msg, err := packName(msg, r.MX, compression)
+	if err != nil {
+		return oldMsg, &nestedError{"MXResource.MX", err}
+	}
+	return msg, nil
+}
+
+func unpackMXResource(hdr ResourceHeader, msg []byte, off int) (*MXResource, error) {
+	pref, off, err := unpackUint16(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Pref", err}
+	}
+	mx, _, err := unpackName(msg, off)
+	if err != nil {
+		return nil, &nestedError{"MX", err}
+	}
+	return &MXResource{hdr, pref, mx}, nil
+}
+
+// An NSResource is an NS Resource record.
+type NSResource struct {
+	ResourceHeader
+
+	NS string
+}
+
+func (r *NSResource) realType() Type {
+	return TypeNS
+}
+
+func (r *NSResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	return packName(msg, r.NS, compression)
+}
+
+func unpackNSResource(hdr ResourceHeader, msg []byte, off int) (*NSResource, error) {
+	ns, _, err := unpackName(msg, off)
+	if err != nil {
+		return nil, err
+	}
+	return &NSResource{hdr, ns}, nil
+}
+
+// A PTRResource is a PTR Resource record.
+type PTRResource struct {
+	ResourceHeader
+
+	PTR string
+}
+
+func (r *PTRResource) realType() Type {
+	return TypePTR
+}
+
+func (r *PTRResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	return packName(msg, r.PTR, compression)
+}
+
+func unpackPTRResource(hdr ResourceHeader, msg []byte, off int) (*PTRResource, error) {
+	ptr, _, err := unpackName(msg, off)
+	if err != nil {
+		return nil, err
+	}
+	return &PTRResource{hdr, ptr}, nil
+}
+
+// An SOAResource is an SOA Resource record.
+type SOAResource struct {
+	ResourceHeader
+
+	NS      string
+	MBox    string
+	Serial  uint32
+	Refresh uint32
+	Retry   uint32
+	Expire  uint32
+
+	// MinTTL the is the default TTL of Resources records which did not
+	// contain a TTL value and the TTL of negative responses. (RFC 2308
+	// Section 4)
+	MinTTL uint32
+}
+
+func (r *SOAResource) realType() Type {
+	return TypeSOA
+}
+
+func (r *SOAResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	oldMsg := msg
+	msg, err := packName(msg, r.NS, compression)
+	if err != nil {
+		return oldMsg, &nestedError{"SOAResource.NS", err}
+	}
+	msg, err = packName(msg, r.MBox, compression)
+	if err != nil {
+		return oldMsg, &nestedError{"SOAResource.MBox", err}
+	}
+	msg = packUint32(msg, r.Serial)
+	msg = packUint32(msg, r.Refresh)
+	msg = packUint32(msg, r.Retry)
+	msg = packUint32(msg, r.Expire)
+	return packUint32(msg, r.MinTTL), nil
+}
+
+func unpackSOAResource(hdr ResourceHeader, msg []byte, off int) (*SOAResource, error) {
+	ns, off, err := unpackName(msg, off)
+	if err != nil {
+		return nil, &nestedError{"NS", err}
+	}
+	mbox, off, err := unpackName(msg, off)
+	if err != nil {
+		return nil, &nestedError{"MBox", err}
+	}
+	serial, off, err := unpackUint32(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Serial", err}
+	}
+	refresh, off, err := unpackUint32(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Refresh", err}
+	}
+	retry, off, err := unpackUint32(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Retry", err}
+	}
+	expire, off, err := unpackUint32(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Expire", err}
+	}
+	minTTL, _, err := unpackUint32(msg, off)
+	if err != nil {
+		return nil, &nestedError{"MinTTL", err}
+	}
+	return &SOAResource{hdr, ns, mbox, serial, refresh, retry, expire, minTTL}, nil
+}
+
+// A TXTResource is a TXT Resource record.
+type TXTResource struct {
+	ResourceHeader
+
+	Txt string // Not a domain name.
+}
+
+func (r *TXTResource) realType() Type {
+	return TypeTXT
+}
+
+func (r *TXTResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	return packText(msg, r.Txt), nil
+}
+
+func unpackTXTResource(hdr ResourceHeader, msg []byte, off int) (*TXTResource, error) {
+	var txt string
+	for n := uint16(0); n < hdr.Length; {
+		var t string
+		var err error
+		if t, off, err = unpackText(msg, off); err != nil {
+			return nil, &nestedError{"text", err}
+		}
+		// Check if we got too many bytes.
+		if hdr.Length-n < uint16(len(t))+1 {
+			return nil, errCalcLen
+		}
+		n += uint16(len(t)) + 1
+		txt += t
+	}
+	return &TXTResource{hdr, txt}, nil
+}
+
+// An SRVResource is an SRV Resource record.
+type SRVResource struct {
+	ResourceHeader
+
+	Priority uint16
+	Weight   uint16
+	Port     uint16
+	Target   string // Not compressed as per RFC 2782.
+}
+
+func (r *SRVResource) realType() Type {
+	return TypeSRV
+}
+
+func (r *SRVResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	oldMsg := msg
+	msg = packUint16(msg, r.Priority)
+	msg = packUint16(msg, r.Weight)
+	msg = packUint16(msg, r.Port)
+	msg, err := packName(msg, r.Target, nil)
+	if err != nil {
+		return oldMsg, &nestedError{"SRVResource.Target", err}
+	}
+	return msg, nil
+}
+
+func unpackSRVResource(hdr ResourceHeader, msg []byte, off int) (*SRVResource, error) {
+	priority, off, err := unpackUint16(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Priority", err}
+	}
+	weight, off, err := unpackUint16(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Weight", err}
+	}
+	port, off, err := unpackUint16(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Port", err}
+	}
+	target, _, err := unpackName(msg, off)
+	if err != nil {
+		return nil, &nestedError{"Target", err}
+	}
+	return &SRVResource{hdr, priority, weight, port, target}, nil
+}
+
+// An AResource is an A Resource record.
+type AResource struct {
+	ResourceHeader
+
+	A [4]byte
+}
+
+func (r *AResource) realType() Type {
+	return TypeA
+}
+
+func (r *AResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	return packBytes(msg, r.A[:]), nil
+}
+
+func unpackAResource(hdr ResourceHeader, msg []byte, off int) (*AResource, error) {
+	var a [4]byte
+	if _, err := unpackBytes(msg, off, a[:]); err != nil {
+		return nil, err
+	}
+	return &AResource{hdr, a}, nil
+}
+
+// An AAAAResource is an AAAA Resource record.
+type AAAAResource struct {
+	ResourceHeader
+
+	AAAA [16]byte
+}
+
+func (r *AAAAResource) realType() Type {
+	return TypeAAAA
+}
+
+func (r *AAAAResource) pack(msg []byte, compression map[string]int) ([]byte, error) {
+	return packBytes(msg, r.AAAA[:]), nil
+}
+
+func unpackAAAAResource(hdr ResourceHeader, msg []byte, off int) (*AAAAResource, error) {
+	var aaaa [16]byte
+	if _, err := unpackBytes(msg, off, aaaa[:]); err != nil {
+		return nil, err
+	}
+	return &AAAAResource{hdr, aaaa}, nil
+}
diff --git a/dns/dnsmessage/message_test.go b/dns/dnsmessage/message_test.go
new file mode 100644
index 0000000..46edd72
--- /dev/null
+++ b/dns/dnsmessage/message_test.go
@@ -0,0 +1,575 @@
+// Copyright 2009 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+package dnsmessage
+
+import (
+	"fmt"
+	"net"
+	"reflect"
+	"strings"
+	"testing"
+)
+
+func (m *Message) String() string {
+	s := fmt.Sprintf("Message: %#v\n", &m.Header)
+	if len(m.Questions) > 0 {
+		s += "-- Questions\n"
+		for _, q := range m.Questions {
+			s += fmt.Sprintf("%#v\n", q)
+		}
+	}
+	if len(m.Answers) > 0 {
+		s += "-- Answers\n"
+		for _, a := range m.Answers {
+			s += fmt.Sprintf("%#v\n", a)
+		}
+	}
+	if len(m.Authorities) > 0 {
+		s += "-- Authorities\n"
+		for _, ns := range m.Authorities {
+			s += fmt.Sprintf("%#v\n", ns)
+		}
+	}
+	if len(m.Additionals) > 0 {
+		s += "-- Additionals\n"
+		for _, e := range m.Additionals {
+			s += fmt.Sprintf("%#v\n", e)
+		}
+	}
+	return s
+}
+
+func TestQuestionPackUnpack(t *testing.T) {
+	want := Question{
+		Name:  ".",
+		Type:  TypeA,
+		Class: ClassINET,
+	}
+	buf, err := want.pack(make([]byte, 1, 50), map[string]int{})
+	if err != nil {
+		t.Fatal("Packing failed:", err)
+	}
+	var p Parser
+	p.msg = buf
+	p.header.questions = 1
+	p.section = sectionQuestions
+	p.off = 1
+	got, err := p.Question()
+	if err != nil {
+		t.Fatalf("Unpacking failed: %v\n%s", err, string(buf[1:]))
+	}
+	if p.off != len(buf) {
+		t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", p.off, len(buf))
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Got = %+v, want = %+v", got, want)
+	}
+}
+
+func TestNamePackUnpack(t *testing.T) {
+	tests := []struct {
+		in   string
+		want string
+		err  error
+	}{
+		{"", ".", nil},
+		{".", ".", nil},
+		{"google..com", "", errZeroSegLen},
+		{"google.com", "google.com.", nil},
+		{"google..com.", "", errZeroSegLen},
+		{"google.com.", "google.com.", nil},
+		{".google.com.", "", errZeroSegLen},
+		{"www..google.com.", "", errZeroSegLen},
+		{"www.google.com.", "www.google.com.", nil},
+	}
+
+	for _, test := range tests {
+		buf, err := packName(make([]byte, 0, 30), test.in, map[string]int{})
+		if err != test.err {
+			t.Errorf("Packing of %s: got err = %v, want err = %v", test.in, err, test.err)
+			continue
+		}
+		if test.err != nil {
+			continue
+		}
+		got, n, err := unpackName(buf, 0)
+		if err != nil {
+			t.Errorf("Unpacking for %s failed: %v", test.in, err)
+			continue
+		}
+		if n != len(buf) {
+			t.Errorf(
+				"Unpacked different amount than packed for %s: got n = %d, want = %d",
+				test.in,
+				n,
+				len(buf),
+			)
+		}
+		if got != test.want {
+			t.Errorf("Unpacking packing of %s: got = %s, want = %s", test.in, got, test.want)
+		}
+	}
+}
+
+func TestDNSPackUnpack(t *testing.T) {
+	wants := []Message{
+		{
+			Questions: []Question{
+				{
+					Name:  ".",
+					Type:  TypeAAAA,
+					Class: ClassINET,
+				},
+			},
+			Answers:     []Resource{},
+			Authorities: []Resource{},
+			Additionals: []Resource{},
+		},
+		largeTestMsg(),
+	}
+	for i, want := range wants {
+		b, err := want.Pack()
+		if err != nil {
+			t.Fatalf("%d: packing failed: %v", i, err)
+		}
+		var got Message
+		err = got.Unpack(b)
+		if err != nil {
+			t.Fatalf("%d: unpacking failed: %v", i, err)
+		}
+		if !reflect.DeepEqual(got, want) {
+			t.Errorf("%d: got = %+v, want = %+v", i, &got, &want)
+		}
+	}
+}
+
+func TestSkipAll(t *testing.T) {
+	msg := largeTestMsg()
+	buf, err := msg.Pack()
+	if err != nil {
+		t.Fatal("Packing large test message:", err)
+	}
+	var p Parser
+	if _, err := p.Start(buf); err != nil {
+		t.Fatal(err)
+	}
+
+	tests := []struct {
+		name string
+		f    func() error
+	}{
+		{"SkipAllQuestions", p.SkipAllQuestions},
+		{"SkipAllAnswers", p.SkipAllAnswers},
+		{"SkipAllAuthorities", p.SkipAllAuthorities},
+		{"SkipAllAdditionals", p.SkipAllAdditionals},
+	}
+	for _, test := range tests {
+		for i := 1; i <= 3; i++ {
+			if err := test.f(); err != nil {
+				t.Errorf("Call #%d to %s(): %v", i, test.name, err)
+			}
+		}
+	}
+}
+
+func TestSkipNotStarted(t *testing.T) {
+	var p Parser
+
+	tests := []struct {
+		name string
+		f    func() error
+	}{
+		{"SkipAllQuestions", p.SkipAllQuestions},
+		{"SkipAllAnswers", p.SkipAllAnswers},
+		{"SkipAllAuthorities", p.SkipAllAuthorities},
+		{"SkipAllAdditionals", p.SkipAllAdditionals},
+	}
+	for _, test := range tests {
+		if err := test.f(); err != ErrNotStarted {
+			t.Errorf("Got %s() = %v, want = %v", test.name, err, ErrNotStarted)
+		}
+	}
+}
+
+func TestTooManyRecords(t *testing.T) {
+	const recs = int(^uint16(0)) + 1
+	tests := []struct {
+		name string
+		msg  Message
+		want error
+	}{
+		{
+			"Questions",
+			Message{
+				Questions: make([]Question, recs),
+			},
+			errTooManyQuestions,
+		},
+		{
+			"Answers",
+			Message{
+				Answers: make([]Resource, recs),
+			},
+			errTooManyAnswers,
+		},
+		{
+			"Authorities",
+			Message{
+				Authorities: make([]Resource, recs),
+			},
+			errTooManyAuthorities,
+		},
+		{
+			"Additionals",
+			Message{
+				Additionals: make([]Resource, recs),
+			},
+			errTooManyAdditionals,
+		},
+	}
+
+	for _, test := range tests {
+		if _, got := test.msg.Pack(); got != test.want {
+			t.Errorf("Packing %d %s: got = %v, want = %v", recs, test.name, got, test.want)
+		}
+	}
+}
+
+func TestVeryLongTxt(t *testing.T) {
+	want := &TXTResource{
+		ResourceHeader: ResourceHeader{
+			Name:  "foo.bar.example.com.",
+			Type:  TypeTXT,
+			Class: ClassINET,
+		},
+		Txt: loremIpsum,
+	}
+	buf, err := packResource(make([]byte, 0, 8000), want, map[string]int{})
+	if err != nil {
+		t.Fatal("Packing failed:", err)
+	}
+	var hdr ResourceHeader
+	off, err := hdr.unpack(buf, 0)
+	if err != nil {
+		t.Fatal("Unpacking ResourceHeader failed:", err)
+	}
+	got, n, err := unpackResource(buf, off, hdr)
+	if err != nil {
+		t.Fatal("Unpacking failed:", err)
+	}
+	if n != len(buf) {
+		t.Errorf("Unpacked different amount than packed: got n = %d, want = %d", n, len(buf))
+	}
+	if !reflect.DeepEqual(got, want) {
+		t.Errorf("Got = %+v, want = %+v", got, want)
+	}
+}
+
+func ExampleHeaderSearch() {
+	msg := Message{
+		Header: Header{Response: true, Authoritative: true},
+		Questions: []Question{
+			{
+				Name:  "foo.bar.example.com.",
+				Type:  TypeA,
+				Class: ClassINET,
+			},
+			{
+				Name:  "bar.example.com.",
+				Type:  TypeA,
+				Class: ClassINET,
+			},
+		},
+		Answers: []Resource{
+			&AResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "foo.bar.example.com.",
+					Type:  TypeA,
+					Class: ClassINET,
+				},
+				A: [4]byte{127, 0, 0, 1},
+			},
+			&AResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "bar.example.com.",
+					Type:  TypeA,
+					Class: ClassINET,
+				},
+				A: [4]byte{127, 0, 0, 2},
+			},
+		},
+	}
+
+	buf, err := msg.Pack()
+	if err != nil {
+		panic(err)
+	}
+
+	wantName := "bar.example.com."
+
+	var p Parser
+	if _, err := p.Start(buf); err != nil {
+		panic(err)
+	}
+
+	for {
+		q, err := p.Question()
+		if err == ErrSectionDone {
+			break
+		}
+		if err != nil {
+			panic(err)
+		}
+
+		if q.Name != wantName {
+			continue
+		}
+
+		fmt.Println("Found question for name", wantName)
+		if err := p.SkipAllQuestions(); err != nil {
+			panic(err)
+		}
+		break
+	}
+
+	var gotIPs []net.IP
+	for {
+		h, err := p.AnswerHeader()
+		if err == ErrSectionDone {
+			break
+		}
+		if err != nil {
+			panic(err)
+		}
+
+		if (h.Type != TypeA && h.Type != TypeAAAA) || h.Class != ClassINET {
+			continue
+		}
+
+		if !strings.EqualFold(h.Name, wantName) {
+			if err := p.SkipAnswer(); err != nil {
+				panic(err)
+			}
+			continue
+		}
+		a, err := p.Answer()
+		if err != nil {
+			panic(err)
+		}
+
+		switch r := a.(type) {
+		default:
+			panic(fmt.Sprintf("unknown type: %T", r))
+		case *AResource:
+			gotIPs = append(gotIPs, r.A[:])
+		case *AAAAResource:
+			gotIPs = append(gotIPs, r.AAAA[:])
+		}
+	}
+
+	fmt.Printf("Found A/AAAA records for name %s: %v\n", wantName, gotIPs)
+
+	// Output:
+	// Found question for name bar.example.com.
+	// Found A/AAAA records for name bar.example.com.: [127.0.0.2]
+}
+
+func largeTestMsg() Message {
+	return Message{
+		Header: Header{Response: true, Authoritative: true},
+		Questions: []Question{
+			{
+				Name:  "foo.bar.example.com.",
+				Type:  TypeA,
+				Class: ClassINET,
+			},
+		},
+		Answers: []Resource{
+			&AResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "foo.bar.example.com.",
+					Type:  TypeA,
+					Class: ClassINET,
+				},
+				A: [4]byte{127, 0, 0, 1},
+			},
+			&AResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "foo.bar.example.com.",
+					Type:  TypeA,
+					Class: ClassINET,
+				},
+				A: [4]byte{127, 0, 0, 2},
+			},
+		},
+		Authorities: []Resource{
+			&NSResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "foo.bar.example.com.",
+					Type:  TypeNS,
+					Class: ClassINET,
+				},
+				NS: "ns1.example.com.",
+			},
+			&NSResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "foo.bar.example.com.",
+					Type:  TypeNS,
+					Class: ClassINET,
+				},
+				NS: "ns2.example.com.",
+			},
+		},
+		Additionals: []Resource{
+			&TXTResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "foo.bar.example.com.",
+					Type:  TypeTXT,
+					Class: ClassINET,
+				},
+				Txt: "So Long, and Thanks for All the Fish",
+			},
+			&TXTResource{
+				ResourceHeader: ResourceHeader{
+					Name:  "foo.bar.example.com.",
+					Type:  TypeTXT,
+					Class: ClassINET,
+				},
+				Txt: "Hamster Huey and the Gooey Kablooie",
+			},
+		},
+	}
+}
+
+const loremIpsum = `
+Lorem ipsum dolor sit amet, nec enim antiopam id, an ullum choro
+nonumes qui, pro eu debet honestatis mediocritatem. No alia enim eos,
+magna signiferumque ex vis. Mei no aperiri dissentias, cu vel quas
+regione. Malorum quaeque vim ut, eum cu semper aliquid invidunt, ei
+nam ipsum assentior.
+
+Nostrum appellantur usu no, vis ex probatus adipiscing. Cu usu illum
+facilis eleifend. Iusto conceptam complectitur vim id. Tale omnesque
+no usu, ei oblique sadipscing vim. At nullam voluptua usu, mei laudem
+reformidans et. Qui ei eros porro reformidans, ius suas veritus
+torquatos ex. Mea te facer alterum consequat.
+
+Soleat torquatos democritum sed et, no mea congue appareat, facer
+aliquam nec in. Has te ipsum tritani. At justo dicta option nec, movet
+phaedrum ad nam. Ea detracto verterem liberavisse has, delectus
+suscipiantur in mei. Ex nam meliore complectitur. Ut nam omnis
+honestatis quaerendum, ea mea nihil affert detracto, ad vix rebum
+mollis.
+
+Ut epicurei praesent neglegentur pri, prima fuisset intellegebat ad
+vim. An habemus comprehensam usu, at enim dignissim pro. Eam reque
+vivendum adipisci ea. Vel ne odio choro minimum. Sea admodum
+dissentiet ex. Mundi tamquam evertitur ius cu. Homero postea iisque ut
+pro, vel ne saepe senserit consetetur.
+
+Nulla utamur facilisis ius ea, in viderer diceret pertinax eum. Mei no
+enim quodsi facilisi, ex sed aeterno appareat mediocritatem, eum
+sententiae deterruisset ut. At suas timeam euismod cum, offendit
+appareat interpretaris ne vix. Vel ea civibus albucius, ex vim quidam
+accusata intellegebat, noluisse instructior sea id. Nec te nonumes
+habemus appellantur, quis dignissim vituperata eu nam.
+
+At vix apeirian patrioque vituperatoribus, an usu agam assum. Debet
+iisque an mea. Per eu dicant ponderum accommodare. Pri alienum
+placerat senserit an, ne eum ferri abhorreant vituperatoribus. Ut mea
+eligendi disputationi. Ius no tation everti impedit, ei magna quidam
+mediocritatem pri.
+
+Legendos perpetua iracundia ne usu, no ius ullum epicurei intellegam,
+ad modus epicuri lucilius eam. In unum quaerendum usu. Ne diam paulo
+has, ea veri virtute sed. Alia honestatis conclusionemque mea eu, ut
+iudico albucius his.
+
+Usu essent probatus eu, sed omnis dolor delicatissimi ex. No qui augue
+dissentias dissentiet. Laudem recteque no usu, vel an velit noluisse,
+an sed utinam eirmod appetere. Ne mea fuisset inimicus ocurreret. At
+vis dicant abhorreant, utinam forensibus nec ne, mei te docendi
+consequat. Brute inermis persecuti cum id. Ut ipsum munere propriae
+usu, dicit graeco disputando id has.
+
+Eros dolore quaerendum nam ei. Timeam ornatus inciderint pro id. Nec
+torquatos sadipscing ei, ancillae molestie per in. Malis principes duo
+ea, usu liber postulant ei.
+
+Graece timeam voluptatibus eu eam. Alia probatus quo no, ea scripta
+feugiat duo. Congue option meliore ex qui, noster invenire appellantur
+ea vel. Eu exerci legendos vel. Consetetur repudiandae vim ut. Vix an
+probo minimum, et nam illud falli tempor.
+
+Cum dico signiferumque eu. Sed ut regione maiorum, id veritus insolens
+tacimates vix. Eu mel sint tamquam lucilius, duo no oporteat
+tacimates. Atqui augue concludaturque vix ei, id mel utroque menandri.
+
+Ad oratio blandit aliquando pro. Vis et dolorum rationibus
+philosophia, ad cum nulla molestie. Hinc fuisset adversarium eum et,
+ne qui nisl verear saperet, vel te quaestio forensibus. Per odio
+option delenit an. Alii placerat has no, in pri nihil platonem
+cotidieque. Est ut elit copiosae scaevola, debet tollit maluisset sea
+an.
+
+Te sea hinc debet pericula, liber ridens fabulas cu sed, quem mutat
+accusam mea et. Elitr labitur albucius et pri, an labore feugait mel.
+Velit zril melius usu ea. Ad stet putent interpretaris qui. Mel no
+error volumus scripserit. In pro paulo iudico, quo ei dolorem
+verterem, affert fabellas dissentiet ea vix.
+
+Vis quot deserunt te. Error aliquid detraxit eu usu, vis alia eruditi
+salutatus cu. Est nostrud bonorum an, ei usu alii salutatus. Vel at
+nisl primis, eum ex aperiri noluisse reformidans. Ad veri velit
+utroque vis, ex equidem detraxit temporibus has.
+
+Inermis appareat usu ne. Eros placerat periculis mea ad, in dictas
+pericula pro. Errem postulant at usu, ea nec amet ornatus mentitum. Ad
+mazim graeco eum, vel ex percipit volutpat iudicabit, sit ne delicata
+interesset. Mel sapientem prodesset abhorreant et, oblique suscipit
+eam id.
+
+An maluisset disputando mea, vidit mnesarchum pri et. Malis insolens
+inciderint no sea. Ea persius maluisset vix, ne vim appellantur
+instructior, consul quidam definiebas pri id. Cum integre feugiat
+pericula in, ex sed persius similique, mel ne natum dicit percipitur.
+
+Primis discere ne pri, errem putent definitionem at vis. Ei mel dolore
+neglegentur, mei tincidunt percipitur ei. Pro ad simul integre
+rationibus. Eu vel alii honestatis definitiones, mea no nonumy
+reprehendunt.
+
+Dicta appareat legendos est cu. Eu vel congue dicunt omittam, no vix
+adhuc minimum constituam, quot noluisse id mel. Eu quot sale mutat
+duo, ex nisl munere invenire duo. Ne nec ullum utamur. Pro alterum
+debitis nostrum no, ut vel aliquid vivendo.
+
+Aliquip fierent praesent quo ne, id sit audiam recusabo delicatissimi.
+Usu postulant incorrupte cu. At pro dicit tibique intellegam, cibo
+dolore impedit id eam, et aeque feugait assentior has. Quando sensibus
+nec ex. Possit sensibus pri ad, unum mutat periculis cu vix.
+
+Mundi tibique vix te, duo simul partiendo qualisque id, est at vidit
+sonet tempor. No per solet aeterno deseruisse. Petentium salutandi
+definiebas pri cu. Munere vivendum est in. Ei justo congue eligendi
+vis, modus offendit omittantur te mel.
+
+Integre voluptaria in qui, sit habemus tractatos constituam no. Utinam
+melius conceptam est ne, quo in minimum apeirian delicata, ut ius
+porro recusabo. Dicant expetenda vix no, ludus scripserit sed ex, eu
+his modo nostro. Ut etiam sonet his, quodsi inciderint philosophia te
+per. Nullam lobortis eu cum, vix an sonet efficiendi repudiandae. Vis
+ad idque fabellas intellegebat.
+
+Eum commodo senserit conclusionemque ex. Sed forensibus sadipscing ut,
+mei in facer delicata periculis, sea ne hinc putent cetero. Nec ne
+alia corpora invenire, alia prima soleat te cum. Eleifend posidonium
+nam at.
+
+Dolorum indoctum cu quo, ex dolor legendos recteque eam, cu pri zril
+discere. Nec civibus officiis dissentiunt ex, est te liber ludus
+elaboraret. Cum ea fabellas invenire. Ex vim nostrud eripuit
+comprehensam, nam te inermis delectus, saepe inermis senserit.
+`
