bluemonk-net-dns 0.5.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/AUTHORS ADDED
@@ -0,0 +1,10 @@
1
+ # $Id: AUTHORS,v 1.2 2005/06/17 10:09:57 bluemonk Exp $
2
+
3
+
4
+ AUTHORS
5
+
6
+ Net::DNS core development:
7
+ Marco Ceresa <ceresa@ieee.org>
8
+
9
+ Beta testing:
10
+
data/CHANGELOG ADDED
@@ -0,0 +1,7 @@
1
+ net-dns 0.4
2
+ - many bug fixes (thanks guys!)
3
+ - a whole new class Net::DNS::Header::RCode
4
+ - new methods in Net::DNS::Resolver class to
5
+ do AXFR queries
6
+ - a new SRV resource record written by Dan Janowski
7
+ - more documentation written and corrected
data/INSTALL ADDED
@@ -0,0 +1,8 @@
1
+ If you didn't install this from gem, you can do a
2
+
3
+ # ruby setup.rb
4
+
5
+ or, from normal user (with sudo)
6
+
7
+ $ rake install
8
+
data/README.rdoc ADDED
@@ -0,0 +1,150 @@
1
+ = Net::DNS
2
+
3
+ Net::DNS is a DNS library written in pure Ruby. It started as a port of Perl Net::DNS module, but it evolved in time into a full Ruby library.
4
+
5
+ Features:
6
+
7
+ - Complete OO interface
8
+ - Clean and intuitive API
9
+ - Modular and flexible
10
+
11
+ == Install
12
+
13
+ Just use Rubygems:
14
+
15
+ $ sudo gem install net-dns
16
+
17
+ If you want to install from source, you can use Rake:
18
+
19
+ $ rake install
20
+
21
+ Or directly from install.rb
22
+
23
+ $ sudo ruby install.rb
24
+
25
+ == API Documentation
26
+
27
+ Visit the page http://marcoceresa.com/net-dns
28
+
29
+ == Trivial resolver
30
+
31
+ The simplest way to use the library is to invoke the Resolver() method:
32
+
33
+ require 'net/dns/resolver'
34
+ p Resolver("www.google.com")
35
+
36
+ The output is compatible with BIND zone files and it's the same you would get with the dig utility.
37
+
38
+ ;; Answer received from localhost:53 (212 bytes)
39
+ ;;
40
+ ;; HEADER SECTION
41
+ ;; id = 64075
42
+ ;; qr = 1 opCode: QUERY aa = 0 tc = 0 rd = 1
43
+ ;; ra = 1 ad = 0 cd = 0 rcode = NoError
44
+ ;; qdCount = 1 anCount = 3 nsCount = 4 arCount = 4
45
+
46
+ ;; QUESTION SECTION (1 record):
47
+ ;; google.com. IN A
48
+
49
+ ;; ANSWER SECTION (3 records):
50
+ google.com. 212 IN A 74.125.45.100
51
+ google.com. 212 IN A 74.125.67.100
52
+ google.com. 212 IN A 209.85.171.100
53
+
54
+ ;; AUTHORITY SECTION (4 records):
55
+ google.com. 345512 IN NS ns1.google.com.
56
+ google.com. 345512 IN NS ns4.google.com.
57
+ google.com. 345512 IN NS ns2.google.com.
58
+ google.com. 345512 IN NS ns3.google.com.
59
+
60
+ ;; ADDITIONAL SECTION (4 records):
61
+ ns1.google.com. 170275 IN A 216.239.32.10
62
+ ns2.google.com. 170275 IN A 216.239.34.10
63
+ ns3.google.com. 170275 IN A 216.239.36.10
64
+ ns4.google.com. 170275 IN A 216.239.38.10
65
+
66
+
67
+ An optional block can be passed yielding the Net::DNS::Packet object
68
+
69
+ Resolver("www.google.com") {|packet| puts packet.size + " bytes"}
70
+ #=> 484 bytes
71
+
72
+ Same for Net::DNS::Resolver.start():
73
+
74
+ Net::DNS::Resolver.start("google.com").answer.size
75
+ #=> 5
76
+
77
+ As optionals parameters, +TYPE+ and +CLASS+ can be specified.
78
+
79
+ p Net::DNS::Resolver.start("google.com", Net::DNS::MX)
80
+
81
+ ;; Answer received from localhost:53 (316 bytes)
82
+ ;;
83
+ ;; HEADER SECTION
84
+ ;; id = 59980
85
+ ;; qr = 1 opCode: QUERY aa = 0 tc = 0 rd = 1
86
+ ;; ra = 1 ad = 0 cd = 0 rcode = NoError
87
+ ;; qdCount = 1 anCount = 4 nsCount = 4 arCount = 8
88
+
89
+ ;; QUESTION SECTION (1 record):
90
+ ;; google.com. IN MX
91
+
92
+ ;; ANSWER SECTION (4 records):
93
+ google.com. 10800 IN MX 10 smtp2.google.com.
94
+ google.com. 10800 IN MX 10 smtp3.google.com.
95
+ google.com. 10800 IN MX 10 smtp4.google.com.
96
+ google.com. 10800 IN MX 10 smtp1.google.com.
97
+
98
+ == Handling the response packet
99
+
100
+ The method Net::DNS::Resolver.start is a wrapper around Resolver.new. It returns a new Net::DNS::Packet object.
101
+
102
+ A DNS packet is divided into 5 sections:
103
+
104
+ - header section # => a Net::DNS::Header object
105
+ - question section # => a Net::DNS::Question object
106
+ - answer section # => an Array of Net::DNS::RR objects
107
+ - authority section # => an Array of Net::DNS::RR objects
108
+ - additional section # => an Array of Net::DNS::RR objects
109
+
110
+ You can access each section by calling the attribute with the same name on a Packet object:
111
+
112
+ packet = Net::DNS::Resolver.start("google.com")
113
+
114
+ header = packet.header
115
+ answer = packet.answer
116
+
117
+ puts "The packet is #{packet.data.size} bytes"
118
+ puts "It contains #{header.anCount} answer entries"
119
+
120
+ answer.any? {|ans| p ans}
121
+
122
+ The output is
123
+
124
+ The packet is 378 bytes
125
+ It contains 3 answer entries
126
+ google.com. 244 IN A 74.125.45.100
127
+ google.com. 244 IN A 74.125.67.100
128
+ google.com. 244 IN A 209.85.171.100
129
+
130
+ A better way to handle the answer section is to use the iterators directly on a Packet object:
131
+
132
+ packet.each_address do |ip|
133
+ puts "#{ip} is alive" if Ping.pingecho(ip.to_s, 10, 80)
134
+ end
135
+
136
+ Gives:
137
+
138
+ 74.125.45.100 is alive
139
+ 74.125.67.100 is alive
140
+ 209.85.171.100 is alive
141
+
142
+
143
+ == Licence
144
+
145
+ Net::DNS is distributed under the same license Ruby is.
146
+
147
+ == Author
148
+
149
+ (c) Marco Ceresa 2006
150
+
data/Rakefile ADDED
@@ -0,0 +1,93 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ #
5
+ # Gem specifications
6
+ #
7
+ SPEC = Gem::Specification.new do |s|
8
+ s.name = "net-dns"
9
+ s.authors = ["Marco Ceresa"]
10
+ s.email = "ceresa@gmail.com"
11
+ s.homepage = "http://github.com/bluemonk/net-dns"
12
+ s.platform = Gem::Platform::RUBY
13
+ s.summary = "Pure Ruby DNS library"
14
+ s.has_rdoc = true
15
+ s.extra_rdoc_files = ["README.rdoc","AUTHORS","INSTALL", "THANKS"]
16
+ s.description = "Net::DNS is a pure Ruby DNS library, with a clean OO interface and an extensible API"
17
+ end
18
+
19
+ begin
20
+ require 'jeweler'
21
+ Jeweler::Tasks.new(SPEC)
22
+ rescue LoadError
23
+ puts "Jeweler not available."
24
+ end
25
+
26
+ require 'rake/testtask'
27
+ Rake::TestTask.new(:test) do |test|
28
+ test.libs << 'lib' << 'test'
29
+ test.pattern = 'test/**/*_test.rb'
30
+ test.verbose = true
31
+ end
32
+
33
+ begin
34
+ require 'rcov/rcovtask'
35
+ Rcov::RcovTask.new do |test|
36
+ test.libs << 'test'
37
+ test.pattern = 'test/**/*_test.rb'
38
+ test.verbose = true
39
+ end
40
+ rescue LoadError
41
+ task :rcov do
42
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
43
+ end
44
+ end
45
+
46
+ task :default => :test
47
+
48
+ require 'rake/rdoctask'
49
+ Rake::RDocTask.new do |rdoc|
50
+ if File.exist?('VERSION.yml')
51
+ config = YAML.load(File.read('VERSION.yml'))
52
+ version = "#{config[:major]}.#{config[:minor]}.#{config[:patch]}"
53
+ else
54
+ puts "Not found!"
55
+ version = ""
56
+ end
57
+
58
+ rdoc.rdoc_dir = 'rdoc'
59
+ rdoc.title = "net-dns #{version}"
60
+ rdoc.rdoc_files.include('README*')
61
+ rdoc.rdoc_files.include('lib/**/*.rb')
62
+ end
63
+
64
+ desc "Upload project on RubyForge"
65
+ task :upload do
66
+ rubyforge = Rake::RubyForgePublisher.new("net-dns","bluemonk")
67
+ rubyforge.upload
68
+ end
69
+
70
+
71
+ def egrep(pattern)
72
+ Dir['**/*.rb'].each do |fn|
73
+ count = 0
74
+ open(fn) do |f|
75
+ while line = f.gets
76
+ count += 1
77
+ if line =~ pattern
78
+ puts "#{fn}:#{count}:#{line}"
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
84
+
85
+ desc "Look for TODO and FIXME tags in the code"
86
+ task :todo do
87
+ egrep /(FIXME|TODO|TBD)/
88
+ end
89
+
90
+
91
+
92
+
93
+
data/THANKS ADDED
@@ -0,0 +1,24 @@
1
+ Many thanks to these wonderful people:
2
+
3
+ - Paul Barry for his excellent article on May07 issue of LinuxJournal, for the kind words and for bug reports
4
+ - Dan Janowski (and his SRV RR)
5
+ - Joshua Abraham
6
+ - Ben April
7
+ - Gene Rogers
8
+ - Nicholas Veeser
9
+ - Gildas Cherruel
10
+ - Alex Dalitz
11
+ - Cory Wright
12
+ - Nicolas Pugnant
13
+ - Andrea Peltrin
14
+ - Giovanni Corriga
15
+ - Luca Russo
16
+ - Pierguido Lambri
17
+ - Andrea Pampuri
18
+ - _koo_
19
+ - Oyku Gencay
20
+ - Eric Liedtke
21
+ - Justin Mercier
22
+ - Daniel Berger
23
+ and all #ruby-lang people
24
+
data/VERSION.yml ADDED
@@ -0,0 +1,4 @@
1
+ ---
2
+ :minor: 5
3
+ :patch: 0
4
+ :major: 0
data/demo/check_soa.rb ADDED
@@ -0,0 +1,120 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # $Id: check_soa.rb,v 1.7 2006/07/30 16:53:57 bluemonk Exp $
4
+
5
+
6
+ require 'rubygems' if "#{RUBY_VERSION}" < "1.9.0"
7
+ require 'net/dns/resolver'
8
+
9
+ #------------------------------------------------------------------------------
10
+ # Get the domain from the command line.
11
+ #------------------------------------------------------------------------------
12
+
13
+ raise ArgumentError, "Usage: check_soa.rb domain\n" unless ARGV.size == 1
14
+
15
+ domain = ARGV[0]
16
+
17
+ #------------------------------------------------------------------------------
18
+ # Find all the nameservers for the domain.
19
+ #------------------------------------------------------------------------------
20
+
21
+ res = Net::DNS::Resolver.new(:defname => false, :retry => 2)
22
+
23
+ #res.defname=false
24
+ #res.retry=2
25
+
26
+
27
+ ns_req = res.query(domain, Net::DNS::NS);
28
+ raise ArgumentError, "No nameservers found for domain: " + res.errorstring +
29
+ "\n" unless ns_req and ns_req.header.anCount > 0
30
+
31
+
32
+ # Send out non-recursive queries
33
+ res.recurse=false
34
+ # Do not buffer standard out
35
+ #| = 1;
36
+
37
+
38
+ #------------------------------------------------------------------------------
39
+ # Check the SOA record on each nameserver.
40
+ #------------------------------------------------------------------------------
41
+
42
+ ns_req.each_nameserver do |ns|
43
+
44
+ #----------------------------------------------------------------------
45
+ # Set the resolver to query this nameserver.
46
+ #----------------------------------------------------------------------
47
+
48
+ # In order to lookup the IP(s) of the nameserver, we need a Resolver
49
+ # object that is set to our local, recursive nameserver. So we create
50
+ # a new object just to do that.
51
+
52
+ local_res = Net::DNS::Resolver.new
53
+
54
+ a_req = local_res.query(ns, Net::DNS::A)
55
+
56
+
57
+ unless a_req
58
+ puts "Can not find address for ns: " + res.errorstring + "\n"
59
+ next
60
+ end
61
+
62
+
63
+ a_req.each_address do |ip|
64
+
65
+ #----------------------------------------------------------------------
66
+ # Ask this IP.
67
+ #----------------------------------------------------------------------
68
+ res.nameservers=ip
69
+
70
+ print "#{ns} (#{ip}): "
71
+
72
+ #----------------------------------------------------------------------
73
+ # Get the SOA record.
74
+ #----------------------------------------------------------------------
75
+
76
+ soa_req = res.send(domain, Net::DNS::SOA, Net::DNS::IN)
77
+
78
+ if soa_req == nil
79
+ puts res.errorstring, "\n"
80
+ next
81
+ end
82
+
83
+ #----------------------------------------------------------------------
84
+ # Is this nameserver authoritative for the domain?
85
+ #----------------------------------------------------------------------
86
+
87
+ unless soa_req.header.auth?
88
+ print "isn't authoritative for domain\n"
89
+ next
90
+ end
91
+
92
+ #----------------------------------------------------------------------
93
+ # We should have received exactly one answer.
94
+ #----------------------------------------------------------------------
95
+
96
+ unless soa_req.header.anCount == 1
97
+ print "expected 1 answer, got " + soa_req.header.anCount.to_s + "\n"
98
+ next
99
+ end
100
+
101
+ #----------------------------------------------------------------------
102
+ # Did we receive an SOA record?
103
+ #----------------------------------------------------------------------
104
+
105
+ unless soa_req.answer[0].class == Net::DNS::RR::SOA
106
+ print "expected SOA, got " + Net::DNS::RR::RRTypes.to_str(soa_req.answer[0].type) + "\n"
107
+ next
108
+ end
109
+
110
+ #----------------------------------------------------------------------
111
+ # Print the serial number.
112
+ #----------------------------------------------------------------------
113
+
114
+ print "has serial number " + soa_req.answer[0].serial.to_s + "\n"
115
+
116
+ end
117
+ end
118
+
119
+
120
+
data/demo/threads.rb ADDED
@@ -0,0 +1,22 @@
1
+ require 'rubygems' if "#{RUBY_VERSION}" < "1.9.0"
2
+ require 'net/dns/resolver'
3
+
4
+ a = ["ibm.com", "sun.com", "redhat.com"]
5
+
6
+ threads = []
7
+
8
+ for dom in a
9
+ threads << Thread.new(dom) do |domain|
10
+ res = Net::DNS::Resolver.new
11
+ res.query(domain, Net::DNS::NS).each_nameserver do |ns|
12
+ puts "Domain #{domain} has nameserver #{ns}"
13
+ end
14
+ puts ""
15
+ end
16
+ end
17
+
18
+ threads.each do |t|
19
+ t.join
20
+ end
21
+
22
+
@@ -0,0 +1,117 @@
1
+ ##
2
+ #
3
+ # dns.rb
4
+ #
5
+ # $id$
6
+ #
7
+ ##
8
+
9
+ module Net # :nodoc:
10
+ module DNS
11
+
12
+ # Version of the library
13
+ VERSION = "0.4"
14
+
15
+ # Packet size in bytes
16
+ PACKETSZ = 512
17
+
18
+ # Size of the header
19
+ HFIXEDSZ = 12
20
+
21
+ # Size of the question portion (type and class)
22
+ QFIXEDSZ = 4
23
+
24
+ # Size of an RR portion (type,class,lenght and ttl)
25
+ RRFIXEDSZ = 10
26
+
27
+ # Size of an int 32 bit
28
+ INT32SZ = 4
29
+
30
+ # Size of a short int
31
+ INT16SZ = 2
32
+
33
+ module QueryTypes
34
+
35
+ SIGZERO = 0
36
+ A = 1
37
+ NS = 2
38
+ MD = 3
39
+ MF = 4
40
+ CNAME = 5
41
+ SOA = 6
42
+ MB = 7
43
+ MG = 8
44
+ MR = 9
45
+ NULL = 10
46
+ WKS = 11
47
+ PTR = 12
48
+ HINFO = 13
49
+ MINFO = 14
50
+ MX = 15
51
+ TXT = 16
52
+ RP = 17
53
+ AFSDB = 18
54
+ X25 = 19
55
+ ISDN = 20
56
+ RT = 21
57
+ NSAP = 22
58
+ NSAPPTR = 23
59
+ SIG = 24
60
+ KEY = 25
61
+ PX = 26
62
+ GPOS = 27
63
+ AAAA = 28
64
+ LOC = 29
65
+ NXT = 30
66
+ EID = 31
67
+ NIMLOC = 32
68
+ SRV = 33
69
+ ATMA = 34
70
+ NAPTR = 35
71
+ KX = 36
72
+ CERT = 37
73
+ DNAME = 39
74
+ OPT = 41
75
+ DS = 43
76
+ SSHFP = 44
77
+ RRSIG = 46
78
+ NSEC = 47
79
+ DNSKEY = 48
80
+ UINFO = 100
81
+ UID = 101
82
+ GID = 102
83
+ UNSPEC = 103
84
+ TKEY = 249
85
+ TSIG = 250
86
+ IXFR = 251
87
+ AXFR = 252
88
+ MAILB = 253
89
+ MAILA = 254
90
+ ANY = 255
91
+
92
+ end
93
+
94
+ module QueryClasses
95
+
96
+ # Internet class
97
+ IN = 1
98
+
99
+ # Chaos class
100
+ CH = 3
101
+
102
+ # Hesiod class
103
+ HS = 4
104
+
105
+ # None class
106
+ NONE = 254
107
+
108
+ # Any class
109
+ ANY = 255
110
+
111
+ end
112
+
113
+ include QueryTypes
114
+ include QueryClasses
115
+
116
+ end # module DNS
117
+ end # module Net