| // Copyright 2017 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_test |
| |
| import ( |
| "fmt" |
| "net" |
| "strings" |
| |
| "internal/x/net/dns/dnsmessage" |
| ) |
| |
| func mustNewName(name string) dnsmessage.Name { |
| n, err := dnsmessage.NewName(name) |
| if err != nil { |
| panic(err) |
| } |
| return n |
| } |
| |
| func ExampleParser() { |
| msg := dnsmessage.Message{ |
| Header: dnsmessage.Header{Response: true, Authoritative: true}, |
| Questions: []dnsmessage.Question{ |
| { |
| Name: mustNewName("foo.bar.example.com."), |
| Type: dnsmessage.TypeA, |
| Class: dnsmessage.ClassINET, |
| }, |
| { |
| Name: mustNewName("bar.example.com."), |
| Type: dnsmessage.TypeA, |
| Class: dnsmessage.ClassINET, |
| }, |
| }, |
| Answers: []dnsmessage.Resource{ |
| { |
| Header: dnsmessage.ResourceHeader{ |
| Name: mustNewName("foo.bar.example.com."), |
| Type: dnsmessage.TypeA, |
| Class: dnsmessage.ClassINET, |
| }, |
| Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 1}}, |
| }, |
| { |
| Header: dnsmessage.ResourceHeader{ |
| Name: mustNewName("bar.example.com."), |
| Type: dnsmessage.TypeA, |
| Class: dnsmessage.ClassINET, |
| }, |
| Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 2}}, |
| }, |
| }, |
| } |
| |
| buf, err := msg.Pack() |
| if err != nil { |
| panic(err) |
| } |
| |
| wantName := "bar.example.com." |
| |
| var p dnsmessage.Parser |
| if _, err := p.Start(buf); err != nil { |
| panic(err) |
| } |
| |
| for { |
| q, err := p.Question() |
| if err == dnsmessage.ErrSectionDone { |
| break |
| } |
| if err != nil { |
| panic(err) |
| } |
| |
| if q.Name.String() != 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 == dnsmessage.ErrSectionDone { |
| break |
| } |
| if err != nil { |
| panic(err) |
| } |
| |
| if (h.Type != dnsmessage.TypeA && h.Type != dnsmessage.TypeAAAA) || h.Class != dnsmessage.ClassINET { |
| continue |
| } |
| |
| if !strings.EqualFold(h.Name.String(), wantName) { |
| if err := p.SkipAnswer(); err != nil { |
| panic(err) |
| } |
| continue |
| } |
| |
| switch h.Type { |
| case dnsmessage.TypeA: |
| r, err := p.AResource() |
| if err != nil { |
| panic(err) |
| } |
| gotIPs = append(gotIPs, r.A[:]) |
| case dnsmessage.TypeAAAA: |
| r, err := p.AAAAResource() |
| if err != nil { |
| panic(err) |
| } |
| 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] |
| } |