-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathdig-authoritative
executable file
·107 lines (91 loc) · 1.68 KB
/
dig-authoritative
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
#!/usr/bin/env ruby
require 'resolv'
require 'set'
def usage
STDERR.puts <<EOM
usage: #{File.basename($0)} [options] NAME [TYPE]
Look up authoritative name servers for NAME (or appropriate parent domain), and
issue a dig query for NAME to those servers.
EOM
end
# http://en.wikipedia.org/wiki/List_of_DNS_record_types#Resource_records
VALID_DNS_RECORD_TYPES = Set.new(%w{
A
AAAA
AFSDB
APL
CAA
CDNSKEY
CDS
CERT
CNAME
DHCID
DLV
DNAME
DNSKEY
DS
HIP
IPSECKEY
KEY
KX
LOC
MX
NAPTR
NS
NSEC
NSEC3
NSEC3PARAM
PTR
RRSIG
RP
SIG
SOA
SRV
SSHFP
TA
TKEY
TLSA
TSIG
TXT
})
def get_ns_servers(name)
Resolv::DNS.open { |dns|
dns.getresources(name, Resolv::DNS::Resource::IN::NS)
}.map {|r| r.name.to_s }
end
def get_ns_servers_for_subdomain(name)
parts = name.split('.')
while !parts.empty?
servers = get_ns_servers(parts.join('.'))
return servers if !servers.empty?
parts.shift
end
raise "Failed to find any NS servers for #{name.inspect}"
end
def main(args)
args = args.dup
# the dig option format is baroque, so we just support a subset
# if the last option is a valid DNS record type, treat args as:
# [options] NAME TYPE
# else:
# [options] NAME
rtype = nil
if args.length >= 2
if VALID_DNS_RECORD_TYPES.include?(args.last.upcase)
rtype = args.pop
end
end
if args.empty?
usage
return 1
end
name = args.pop
nameservers = get_ns_servers_for_subdomain(name)
dig_args = nameservers.map {|s| '@' + s} + args + [name]
dig_args << rtype if rtype
STDERR.puts('+ dig ' + dig_args.join(' '))
exec(['dig', 'dig'], *dig_args)
end
if $0 == __FILE__
main(ARGV)
end