bluemonk-net-dns 0.5.0

Sign up to get free protection for your applications and to get access to all the features.
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