example_test.go 2.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132
  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. package dnsmessage_test
  5. import (
  6. "fmt"
  7. "net"
  8. "strings"
  9. "golang.org/x/net/dns/dnsmessage"
  10. )
  11. func mustNewName(name string) dnsmessage.Name {
  12. n, err := dnsmessage.NewName(name)
  13. if err != nil {
  14. panic(err)
  15. }
  16. return n
  17. }
  18. func ExampleParser() {
  19. msg := dnsmessage.Message{
  20. Header: dnsmessage.Header{Response: true, Authoritative: true},
  21. Questions: []dnsmessage.Question{
  22. {
  23. Name: mustNewName("foo.bar.example.com."),
  24. Type: dnsmessage.TypeA,
  25. Class: dnsmessage.ClassINET,
  26. },
  27. {
  28. Name: mustNewName("bar.example.com."),
  29. Type: dnsmessage.TypeA,
  30. Class: dnsmessage.ClassINET,
  31. },
  32. },
  33. Answers: []dnsmessage.Resource{
  34. {
  35. Header: dnsmessage.ResourceHeader{
  36. Name: mustNewName("foo.bar.example.com."),
  37. Type: dnsmessage.TypeA,
  38. Class: dnsmessage.ClassINET,
  39. },
  40. Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 1}},
  41. },
  42. {
  43. Header: dnsmessage.ResourceHeader{
  44. Name: mustNewName("bar.example.com."),
  45. Type: dnsmessage.TypeA,
  46. Class: dnsmessage.ClassINET,
  47. },
  48. Body: &dnsmessage.AResource{A: [4]byte{127, 0, 0, 2}},
  49. },
  50. },
  51. }
  52. buf, err := msg.Pack()
  53. if err != nil {
  54. panic(err)
  55. }
  56. wantName := "bar.example.com."
  57. var p dnsmessage.Parser
  58. if _, err := p.Start(buf); err != nil {
  59. panic(err)
  60. }
  61. for {
  62. q, err := p.Question()
  63. if err == dnsmessage.ErrSectionDone {
  64. break
  65. }
  66. if err != nil {
  67. panic(err)
  68. }
  69. if q.Name.String() != wantName {
  70. continue
  71. }
  72. fmt.Println("Found question for name", wantName)
  73. if err := p.SkipAllQuestions(); err != nil {
  74. panic(err)
  75. }
  76. break
  77. }
  78. var gotIPs []net.IP
  79. for {
  80. h, err := p.AnswerHeader()
  81. if err == dnsmessage.ErrSectionDone {
  82. break
  83. }
  84. if err != nil {
  85. panic(err)
  86. }
  87. if (h.Type != dnsmessage.TypeA && h.Type != dnsmessage.TypeAAAA) || h.Class != dnsmessage.ClassINET {
  88. continue
  89. }
  90. if !strings.EqualFold(h.Name.String(), wantName) {
  91. if err := p.SkipAnswer(); err != nil {
  92. panic(err)
  93. }
  94. continue
  95. }
  96. switch h.Type {
  97. case dnsmessage.TypeA:
  98. r, err := p.AResource()
  99. if err != nil {
  100. panic(err)
  101. }
  102. gotIPs = append(gotIPs, r.A[:])
  103. case dnsmessage.TypeAAAA:
  104. r, err := p.AAAAResource()
  105. if err != nil {
  106. panic(err)
  107. }
  108. gotIPs = append(gotIPs, r.AAAA[:])
  109. }
  110. }
  111. fmt.Printf("Found A/AAAA records for name %s: %v\n", wantName, gotIPs)
  112. // Output:
  113. // Found question for name bar.example.com.
  114. // Found A/AAAA records for name bar.example.com.: [127.0.0.2]
  115. }