forked from tomsteele/blacksheepwall
/
generic.go
156 lines (144 loc) · 3.68 KB
/
generic.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
package bsw
import (
"errors"
"strings"
"github.com/miekg/dns"
)
// LookupMX returns all the mx servers for a domain.
func LookupMX(domain, serverAddr string) ([]string, error) {
servers := []string{}
m := &dns.Msg{}
m.SetQuestion(dns.Fqdn(domain), dns.TypeMX)
in, err := dns.Exchange(m, serverAddr+":53")
if err != nil {
return servers, err
}
if len(in.Answer) < 1 {
return servers, errors.New("no Answer")
}
for _, a := range in.Answer {
if mx, ok := a.(*dns.MX); ok {
parts := strings.Split(mx.Mx, " ")
if len(parts) < 1 {
continue
}
servers = append(servers, parts[len(parts)-1])
}
}
return servers, nil
}
// LookupNS returns the names servers for a domain.
func LookupNS(domain, serverAddr string) ([]string, error) {
servers := []string{}
m := &dns.Msg{}
m.SetQuestion(dns.Fqdn(domain), dns.TypeNS)
in, err := dns.Exchange(m, serverAddr+":53")
if err != nil {
return servers, err
}
if len(in.Answer) < 1 {
return servers, errors.New("no Answer")
}
for _, a := range in.Answer {
if ns, ok := a.(*dns.NS); ok {
servers = append(servers, ns.Ns)
}
}
return servers, nil
}
// LookupIP returns hostname from PTR record or error.
func LookupIP(ip, serverAddr string) ([]string, error) {
names := []string{}
m := &dns.Msg{}
ipArpa, err := dns.ReverseAddr(ip)
if err != nil {
return names, err
}
m.SetQuestion(ipArpa, dns.TypePTR)
in, err := dns.Exchange(m, serverAddr+":53")
if err != nil {
return names, err
}
if len(in.Answer) < 1 {
return names, errors.New("no Answer")
}
for _, a := range in.Answer {
if ptr, ok := a.(*dns.PTR); ok {
if strings.Contains(ptr.Ptr, strings.Join(strings.Split(ip, "."), "-")) {
continue
}
names = append(names, strings.TrimRight(ptr.Ptr, "."))
}
}
if len(names) < 1 {
return names, errors.New("no PTR")
}
return names, nil
}
// LookupName returns IPv4 address from A record or error.
func LookupName(fqdn, serverAddr string) (string, error) {
m := &dns.Msg{}
m.SetQuestion(dns.Fqdn(fqdn), dns.TypeA)
in, err := dns.Exchange(m, serverAddr+":53")
if err != nil {
return "", err
}
if len(in.Answer) < 1 {
return "", errors.New("no Answer")
}
if a, ok := in.Answer[0].(*dns.A); ok {
ip := a.A.String()
return ip, nil
}
return "", errors.New("no A record returned")
}
// LookupCname returns a fqdn address from CNAME record or error.
func LookupCname(fqdn, serverAddr string) (string, error) {
m := &dns.Msg{}
m.SetQuestion(dns.Fqdn(fqdn), dns.TypeCNAME)
in, err := dns.Exchange(m, serverAddr+":53")
if err != nil {
return "", err
}
if len(in.Answer) < 1 {
return "", errors.New("no Answer")
}
if a, ok := in.Answer[0].(*dns.CNAME); ok {
name := a.Target
return strings.TrimRight(name, "."), nil
}
return "", errors.New("no CNAME record returned")
}
// LookupName6 returns a IPv6 address from AAAA record or error.
func LookupName6(fqdn, serverAddr string) (string, error) {
m := &dns.Msg{}
m.SetQuestion(dns.Fqdn(fqdn), dns.TypeAAAA)
in, err := dns.Exchange(m, serverAddr+":53")
if err != nil {
return "", err
}
if len(in.Answer) < 1 {
return "", errors.New("no Answer")
}
if a, ok := in.Answer[0].(*dns.AAAA); ok {
ip := a.AAAA.String()
return ip, nil
}
return "", errors.New("no AAAA record returned")
}
// LookupSRV returns a hostname from SRV record or error.
func LookupSRV(fqdn, dnsServer string) (string, error) {
m := &dns.Msg{}
m.SetQuestion(dns.Fqdn(fqdn), dns.TypeSRV)
in, err := dns.Exchange(m, dnsServer+":53")
if err != nil {
return "", err
}
if len(in.Answer) < 1 {
return "", errors.New("no Answer")
}
if a, ok := in.Answer[0].(*dns.SRV); ok {
return strings.TrimRight(a.Target, "."), nil
}
return "", errors.New("no SRV record returned")
}