1package dns_test 2 3import ( 4 "errors" 5 "fmt" 6 "log" 7 "net" 8 9 "github.com/miekg/dns" 10) 11 12// Retrieve the MX records for miek.nl. 13func ExampleMX() { 14 config, _ := dns.ClientConfigFromFile("/etc/resolv.conf") 15 c := new(dns.Client) 16 m := new(dns.Msg) 17 m.SetQuestion("miek.nl.", dns.TypeMX) 18 m.RecursionDesired = true 19 r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port) 20 if err != nil { 21 return 22 } 23 if r.Rcode != dns.RcodeSuccess { 24 return 25 } 26 for _, a := range r.Answer { 27 if mx, ok := a.(*dns.MX); ok { 28 fmt.Printf("%s\n", mx.String()) 29 } 30 } 31} 32 33// Retrieve the DNSKEY records of a zone and convert them 34// to DS records for SHA1, SHA256 and SHA384. 35func ExampleDS() { 36 config, _ := dns.ClientConfigFromFile("/etc/resolv.conf") 37 c := new(dns.Client) 38 m := new(dns.Msg) 39 zone := "miek.nl" 40 m.SetQuestion(dns.Fqdn(zone), dns.TypeDNSKEY) 41 m.SetEdns0(4096, true) 42 r, _, err := c.Exchange(m, config.Servers[0]+":"+config.Port) 43 if err != nil { 44 return 45 } 46 if r.Rcode != dns.RcodeSuccess { 47 return 48 } 49 for _, k := range r.Answer { 50 if key, ok := k.(*dns.DNSKEY); ok { 51 for _, alg := range []uint8{dns.SHA1, dns.SHA256, dns.SHA384} { 52 fmt.Printf("%s; %d\n", key.ToDS(alg).String(), key.Flags) 53 } 54 } 55 } 56} 57 58const TypeAPAIR = 0x0F99 59 60type APAIR struct { 61 addr [2]net.IP 62} 63 64func NewAPAIR() dns.PrivateRdata { return new(APAIR) } 65 66func (rd *APAIR) String() string { return rd.addr[0].String() + " " + rd.addr[1].String() } 67func (rd *APAIR) Parse(txt []string) error { 68 if len(txt) != 2 { 69 return errors.New("two addresses required for APAIR") 70 } 71 for i, s := range txt { 72 ip := net.ParseIP(s) 73 if ip == nil { 74 return errors.New("invalid IP in APAIR text representation") 75 } 76 rd.addr[i] = ip 77 } 78 return nil 79} 80 81func (rd *APAIR) Pack(buf []byte) (int, error) { 82 b := append([]byte(rd.addr[0]), []byte(rd.addr[1])...) 83 n := copy(buf, b) 84 if n != len(b) { 85 return n, dns.ErrBuf 86 } 87 return n, nil 88} 89 90func (rd *APAIR) Unpack(buf []byte) (int, error) { 91 ln := net.IPv4len * 2 92 if len(buf) != ln { 93 return 0, errors.New("invalid length of APAIR rdata") 94 } 95 cp := make([]byte, ln) 96 copy(cp, buf) // clone bytes to use them in IPs 97 98 rd.addr[0] = net.IP(cp[:3]) 99 rd.addr[1] = net.IP(cp[4:]) 100 101 return len(buf), nil 102} 103 104func (rd *APAIR) Copy(dest dns.PrivateRdata) error { 105 cp := make([]byte, rd.Len()) 106 _, err := rd.Pack(cp) 107 if err != nil { 108 return err 109 } 110 111 d := dest.(*APAIR) 112 d.addr[0] = net.IP(cp[:3]) 113 d.addr[1] = net.IP(cp[4:]) 114 return nil 115} 116 117func (rd *APAIR) Len() int { 118 return net.IPv4len * 2 119} 120 121func ExamplePrivateHandle() { 122 dns.PrivateHandle("APAIR", TypeAPAIR, NewAPAIR) 123 defer dns.PrivateHandleRemove(TypeAPAIR) 124 125 rr, err := dns.NewRR("miek.nl. APAIR (1.2.3.4 1.2.3.5)") 126 if err != nil { 127 log.Fatal("could not parse APAIR record: ", err) 128 } 129 fmt.Println(rr) 130 // Output: miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5 131 132 m := new(dns.Msg) 133 m.Id = 12345 134 m.SetQuestion("miek.nl.", TypeAPAIR) 135 m.Answer = append(m.Answer, rr) 136 137 fmt.Println(m) 138 // ;; opcode: QUERY, status: NOERROR, id: 12345 139 // ;; flags: rd; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0 140 // 141 // ;; QUESTION SECTION: 142 // ;miek.nl. IN APAIR 143 // 144 // ;; ANSWER SECTION: 145 // miek.nl. 3600 IN APAIR 1.2.3.4 1.2.3.5 146} 147