1// Copyright 2017 The Go Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style
3// license that can be found in the LICENSE file.
4
5// +build ignore
6
7package dnsmessage_test
8
9import (
10	"fmt"
11	"net"
12	"strings"
13
14	"internal/x/net/dns/dnsmessage"
15)
16
17func mustNewName(name string) dnsmessage.Name {
18	n, err := dnsmessage.NewName(name)
19	if err != nil {
20		panic(err)
21	}
22	return n
23}
24
25func ExampleParser() {
26	msg := dnsmessage.Message{
27		Header: dnsmessage.Header{Response: true, Authoritative: true},
28		Questions: []dnsmessage.Question{
29			{
30				Name:  mustNewName("foo.bar.example.com."),
31				Type:  dnsmessage.TypeA,
32				Class: dnsmessage.ClassINET,
33			},
34			{
35				Name:  mustNewName("bar.example.com."),
36				Type:  dnsmessage.TypeA,
37				Class: dnsmessage.ClassINET,
38			},
39		},
40		Answers: []dnsmessage.Resource{
41			{
42				Header: dnsmessage.ResourceHeader{
43					Name:  mustNewName("foo.bar.example.com."),
44					Type:  dnsmessage.TypeA,
45					Class: dnsmessage.ClassINET,
46				},
47				Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 1}},
48			},
49			{
50				Header: dnsmessage.ResourceHeader{
51					Name:  mustNewName("bar.example.com."),
52					Type:  dnsmessage.TypeA,
53					Class: dnsmessage.ClassINET,
54				},
55				Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 2}},
56			},
57		},
58	}
59
60	buf, err := msg.Pack()
61	if err != nil {
62		panic(err)
63	}
64
65	wantName := "bar.example.com."
66
67	var p dnsmessage.Parser
68	if _, err := p.Start(buf); err != nil {
69		panic(err)
70	}
71
72	for {
73		q, err := p.Question()
74		if err == dnsmessage.ErrSectionDone {
75			break
76		}
77		if err != nil {
78			panic(err)
79		}
80
81		if q.Name.String() != wantName {
82			continue
83		}
84
85		fmt.Println("Found question for name", wantName)
86		if err := p.SkipAllQuestions(); err != nil {
87			panic(err)
88		}
89		break
90	}
91
92	var gotIPs []net.IP
93	for {
94		h, err := p.AnswerHeader()
95		if err == dnsmessage.ErrSectionDone {
96			break
97		}
98		if err != nil {
99			panic(err)
100		}
101
102		if (h.Type != dnsmessage.TypeA && h.Type != dnsmessage.TypeAAAA) || h.Class != dnsmessage.ClassINET {
103			continue
104		}
105
106		if !strings.EqualFold(h.Name.String(), wantName) {
107			if err := p.SkipAnswer(); err != nil {
108				panic(err)
109			}
110			continue
111		}
112
113		switch h.Type {
114		case dnsmessage.TypeA:
115			r, err := p.AResource()
116			if err != nil {
117				panic(err)
118			}
119			gotIPs = append(gotIPs, r.A[:])
120		case dnsmessage.TypeAAAA:
121			r, err := p.AAAAResource()
122			if err != nil {
123				panic(err)
124			}
125			gotIPs = append(gotIPs, r.AAAA[:])
126		}
127	}
128
129	fmt.Printf("Found A/AAAA records for name %s: %v\n", wantName, gotIPs)
130
131	// Output:
132	// Found question for name bar.example.com.
133	// Found A/AAAA records for name bar.example.com.: [127.0.0.2]
134}
135