faildns 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/bin/failnamed +203 -0
- data/bin/failresolve +37 -0
- data/lib/faildns.rb +20 -0
- data/lib/faildns/class.rb +96 -0
- data/lib/faildns/client.rb +114 -0
- data/lib/faildns/common.rb +52 -0
- data/lib/faildns/domainname.rb +223 -0
- data/lib/faildns/header.rb +254 -0
- data/lib/faildns/header/opcode.rb +95 -0
- data/lib/faildns/header/status.rb +123 -0
- data/lib/faildns/header/type.rb +72 -0
- data/lib/faildns/ip.rb +57 -0
- data/lib/faildns/message.rb +100 -0
- data/lib/faildns/qclass.rb +51 -0
- data/lib/faildns/qtype.rb +60 -0
- data/lib/faildns/question.rb +101 -0
- data/lib/faildns/resourcerecord.rb +140 -0
- data/lib/faildns/resourcerecord/IN.rb +29 -0
- data/lib/faildns/resourcerecord/IN/A.rb +75 -0
- data/lib/faildns/resourcerecord/IN/AAAA.rb +77 -0
- data/lib/faildns/resourcerecord/IN/CNAME.rb +70 -0
- data/lib/faildns/resourcerecord/IN/HINFO.rb +79 -0
- data/lib/faildns/resourcerecord/IN/MX.rb +75 -0
- data/lib/faildns/resourcerecord/IN/NS.rb +77 -0
- data/lib/faildns/resourcerecord/IN/NULL.rb +66 -0
- data/lib/faildns/resourcerecord/IN/PTR.rb +69 -0
- data/lib/faildns/resourcerecord/IN/SOA.rb +128 -0
- data/lib/faildns/resourcerecord/IN/TXT.rb +63 -0
- data/lib/faildns/resourcerecord/data.rb +41 -0
- data/lib/faildns/server.rb +71 -0
- data/lib/faildns/server/dispatcher.rb +181 -0
- data/lib/faildns/server/dispatcher/connectiondispatcher.rb +93 -0
- data/lib/faildns/server/dispatcher/event.rb +47 -0
- data/lib/faildns/server/dispatcher/eventdispatcher.rb +73 -0
- data/lib/faildns/server/dispatcher/socket.rb +93 -0
- data/lib/faildns/type.rb +186 -0
- metadata +100 -0
@@ -0,0 +1,51 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of faildns.
|
5
|
+
#
|
6
|
+
# faildns is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# faildns is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with faildns. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'faildns/class'
|
21
|
+
|
22
|
+
module DNS
|
23
|
+
|
24
|
+
#--
|
25
|
+
# QCLASS fields appear in the question section of a query. QCLASS values
|
26
|
+
# are a superset of CLASS values; every CLASS is a valid QCLASS. In
|
27
|
+
# addition to CLASS values, the following QCLASSes are defined:
|
28
|
+
#
|
29
|
+
# * 255 any class
|
30
|
+
#++
|
31
|
+
|
32
|
+
class QClass < Class
|
33
|
+
Values = {
|
34
|
+
254 => :NONE,
|
35
|
+
255 => :ANY
|
36
|
+
}
|
37
|
+
|
38
|
+
def initialize (value)
|
39
|
+
super(value)
|
40
|
+
end
|
41
|
+
|
42
|
+
def to_sym
|
43
|
+
Values[@value] || Class::Values[@value]
|
44
|
+
end
|
45
|
+
|
46
|
+
def to_s
|
47
|
+
(Values[@value] || Class::Values[@value]).to_s
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of faildns.
|
5
|
+
#
|
6
|
+
# faildns is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# faildns is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with faildns. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'faildns/type'
|
21
|
+
|
22
|
+
module DNS
|
23
|
+
|
24
|
+
#--
|
25
|
+
# QTYPE fields appear in the question part of a query. QTYPES are a
|
26
|
+
# superset of TYPEs, hence all TYPEs are valid QTYPEs. In addition, the
|
27
|
+
# following QTYPEs are defined:
|
28
|
+
#
|
29
|
+
#
|
30
|
+
# AXFR 252 A request for a transfer of an entire zone
|
31
|
+
#
|
32
|
+
# MAILB 253 A request for mailbox-related records (MB, MG or MR)
|
33
|
+
#
|
34
|
+
# MAILA 254 A request for mail agent RRs (Obsolete - see MX)
|
35
|
+
#
|
36
|
+
# * 255 A request for all records
|
37
|
+
#++
|
38
|
+
|
39
|
+
class QType < Type
|
40
|
+
Values = {
|
41
|
+
252 => :AXFR,
|
42
|
+
253 => :MAILB,
|
43
|
+
254 => :MAILA,
|
44
|
+
255 => :ANY
|
45
|
+
}
|
46
|
+
|
47
|
+
def initialize (value)
|
48
|
+
super(value)
|
49
|
+
end
|
50
|
+
|
51
|
+
def to_sym
|
52
|
+
Values[@value] || Type::Values[@value]
|
53
|
+
end
|
54
|
+
|
55
|
+
def to_s
|
56
|
+
(Values[@value] || Type::Values[@value]).to_s
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,101 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of faildns.
|
5
|
+
#
|
6
|
+
# faildns is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# faildns is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with faildns. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'faildns/domainname'
|
21
|
+
require 'faildns/qtype'
|
22
|
+
require 'faildns/qclass'
|
23
|
+
|
24
|
+
module DNS
|
25
|
+
|
26
|
+
#--
|
27
|
+
# The question section is used to carry the "question" in most queries,
|
28
|
+
# i.e., the parameters that define what is being asked. The section
|
29
|
+
# contains QDCOUNT (usually 1) entries, each of the following format:
|
30
|
+
#
|
31
|
+
# 1 1 1 1 1 1
|
32
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
33
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
34
|
+
# | |
|
35
|
+
# / QNAME /
|
36
|
+
# / /
|
37
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
38
|
+
# | QTYPE |
|
39
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
40
|
+
# | QCLASS |
|
41
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
42
|
+
#
|
43
|
+
# where:
|
44
|
+
#
|
45
|
+
# QNAME a domain name represented as a sequence of labels, where
|
46
|
+
# each label consists of a length octet followed by that
|
47
|
+
# number of octets. The domain name terminates with the
|
48
|
+
# zero length octet for the null label of the root. Note
|
49
|
+
# that this field may be an odd number of octets; no
|
50
|
+
# padding is used.
|
51
|
+
#
|
52
|
+
# QTYPE a two octet code which specifies the type of the query.
|
53
|
+
# The values for this field include all codes valid for a
|
54
|
+
# TYPE field, together with some more general codes which
|
55
|
+
# can match more than one type of RR.
|
56
|
+
#
|
57
|
+
# QCLASS a two octet code that specifies the class of the query.
|
58
|
+
# For example, the QCLASS field is IN for the Internet.
|
59
|
+
#++
|
60
|
+
|
61
|
+
class Question
|
62
|
+
def self.parse (string, original)
|
63
|
+
Question.new {|q|
|
64
|
+
q.name = DomainName.parse(string, original);
|
65
|
+
q.type = QType.parse(string);
|
66
|
+
q.class = QClass.parse(string);
|
67
|
+
}
|
68
|
+
end
|
69
|
+
|
70
|
+
def self.length (string)
|
71
|
+
DomainName.length(string) + QType.length + QClass.length
|
72
|
+
|
73
|
+
return result
|
74
|
+
end
|
75
|
+
|
76
|
+
def initialize (what={})
|
77
|
+
if !what.is_a? Hash
|
78
|
+
raise ArgumentError.new('You have to pass a Hash.')
|
79
|
+
end
|
80
|
+
|
81
|
+
@data = what
|
82
|
+
|
83
|
+
if block_given?
|
84
|
+
yield self
|
85
|
+
end
|
86
|
+
end
|
87
|
+
|
88
|
+
def name; @data[:QNAME] end
|
89
|
+
def type; @data[:QTYPE] end
|
90
|
+
def class; @data[:QCLASS] end
|
91
|
+
|
92
|
+
def name= (val); @data[:QNAME] = DomainName.new(val) end
|
93
|
+
def type= (val); @data[:QTYPE] = QType.new(val) end
|
94
|
+
def class= (val); @data[:QCLASS] = QClass.new(val) end
|
95
|
+
|
96
|
+
def pack
|
97
|
+
self.name.pack + self.type.pack + self.class.pack
|
98
|
+
end
|
99
|
+
end
|
100
|
+
|
101
|
+
end
|
@@ -0,0 +1,140 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of faildns.
|
5
|
+
#
|
6
|
+
# faildns is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# faildns is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with faildns. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'faildns/resourcerecord/IN'
|
21
|
+
|
22
|
+
module DNS
|
23
|
+
|
24
|
+
#--
|
25
|
+
# The answer, authority, and additional sections all share the same
|
26
|
+
# format: a variable number of resource records, where the number of
|
27
|
+
# records is specified in the corresponding count field in the header.
|
28
|
+
# Each resource record has the following format:
|
29
|
+
# 1 1 1 1 1 1
|
30
|
+
# 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
|
31
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
32
|
+
# | |
|
33
|
+
# / /
|
34
|
+
# / NAME /
|
35
|
+
# | |
|
36
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
37
|
+
# | TYPE |
|
38
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
39
|
+
# | CLASS |
|
40
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
41
|
+
# | TTL |
|
42
|
+
# | |
|
43
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
44
|
+
# | RDLENGTH |
|
45
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--|
|
46
|
+
# / RDATA /
|
47
|
+
# / /
|
48
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
49
|
+
#
|
50
|
+
# where:
|
51
|
+
#
|
52
|
+
# NAME a domain name to which this resource record pertains.
|
53
|
+
#
|
54
|
+
# TYPE two octets containing one of the RR type codes. This
|
55
|
+
# field specifies the meaning of the data in the RDATA
|
56
|
+
# field.
|
57
|
+
#
|
58
|
+
# CLASS two octets which specify the class of the data in the
|
59
|
+
# RDATA field.
|
60
|
+
#
|
61
|
+
# TTL a 32 bit unsigned integer that specifies the time
|
62
|
+
# interval (in seconds) that the resource record may be
|
63
|
+
# cached before it should be discarded. Zero values are
|
64
|
+
# interpreted to mean that the RR can only be used for the
|
65
|
+
# transaction in progress, and should not be cached.
|
66
|
+
#
|
67
|
+
# RDLENGTH an unsigned 16 bit integer that specifies the length in
|
68
|
+
# octets of the RDATA field.
|
69
|
+
#
|
70
|
+
# RDATA a variable length string of octets that describes the
|
71
|
+
# resource. The format of this information varies
|
72
|
+
# according to the TYPE and CLASS of the resource record.
|
73
|
+
# For example, the if the TYPE is A and the CLASS is IN,
|
74
|
+
# the RDATA field is a 4 octet ARPA Internet address.
|
75
|
+
#++
|
76
|
+
|
77
|
+
class ResourceRecord
|
78
|
+
def self.parse (string, original)
|
79
|
+
string.force_encoding 'BINARY'
|
80
|
+
|
81
|
+
ResourceRecord.new {|r|
|
82
|
+
r.name = DomainName.parse(string, original)
|
83
|
+
r.type = Type.parse(string)
|
84
|
+
r.class = Class.parse(string)
|
85
|
+
|
86
|
+
r.ttl = string.unpack('N').first; string[0, 4] = ''
|
87
|
+
|
88
|
+
r.length = string.unpack('n').first; string[0, 2] = ''
|
89
|
+
r.data = ResourceRecord.const_get(r.class.to_sym).const_get(r.type.to_sym) rescue nil
|
90
|
+
|
91
|
+
if !r.data
|
92
|
+
r.data = ResourceRecord.const_get(r.class.to_sym).const_get(:NULL)
|
93
|
+
DNS.debug "ResourceRecord::#{r.class}::#{r.type} not found."
|
94
|
+
end
|
95
|
+
|
96
|
+
DNS.debug r.data.inspect, { :level => 2 }
|
97
|
+
|
98
|
+
r.data = r.data.parse(string, r.length, original)
|
99
|
+
}
|
100
|
+
end
|
101
|
+
|
102
|
+
def self.length (string)
|
103
|
+
string.force_encoding 'BINARY'
|
104
|
+
|
105
|
+
(tmp = DomainName.length(string) + Type.length + Class.length + 4) + string[tmp, 2].unpack('n').first + 2
|
106
|
+
end
|
107
|
+
|
108
|
+
def initialize (what={})
|
109
|
+
if !what.is_a? Hash
|
110
|
+
raise ArgumentError.new('You have to pass a Hash.')
|
111
|
+
end
|
112
|
+
|
113
|
+
@data = what
|
114
|
+
|
115
|
+
if block_given?
|
116
|
+
yield self
|
117
|
+
end
|
118
|
+
end
|
119
|
+
|
120
|
+
def name; @data[:NAME] end
|
121
|
+
def type; @data[:TYPE] end
|
122
|
+
def class; @data[:CLASS] end
|
123
|
+
def ttl; @data[:TTL] end
|
124
|
+
def length; @data[:RDLENGTH] end
|
125
|
+
def data; @data[:RDATA] end
|
126
|
+
|
127
|
+
def name= (val); @data[:NAME] = DomainName.new(val) end
|
128
|
+
def type= (val); @data[:TYPE] = Type.new(val) end
|
129
|
+
def class= (val); @data[:CLASS] = Class.new(val) end
|
130
|
+
def ttl= (val); @data[:TTL] = val end
|
131
|
+
def length= (val); @data[:RDLENGTH] = val end
|
132
|
+
def data= (val); @data[:RDATA] = val end
|
133
|
+
|
134
|
+
def pack
|
135
|
+
self.name.pack + self.type.pack + self.class.pack + [self.ttl].pack('N') +
|
136
|
+
[self.length].pack('n') + self.data.pack
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of faildns.
|
5
|
+
#
|
6
|
+
# faildns is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# faildns is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with faildns. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'faildns/resourcerecord/IN/A'
|
21
|
+
require 'faildns/resourcerecord/IN/CNAME'
|
22
|
+
require 'faildns/resourcerecord/IN/HINFO'
|
23
|
+
require 'faildns/resourcerecord/IN/MX'
|
24
|
+
require 'faildns/resourcerecord/IN/NS'
|
25
|
+
require 'faildns/resourcerecord/IN/NULL'
|
26
|
+
require 'faildns/resourcerecord/IN/PTR'
|
27
|
+
require 'faildns/resourcerecord/IN/SOA'
|
28
|
+
require 'faildns/resourcerecord/IN/TXT'
|
29
|
+
require 'faildns/resourcerecord/IN/AAAA'
|
@@ -0,0 +1,75 @@
|
|
1
|
+
#--
|
2
|
+
# Copyleft meh. [http://meh.doesntexist.org | meh@paranoici.org]
|
3
|
+
#
|
4
|
+
# This file is part of faildns.
|
5
|
+
#
|
6
|
+
# faildns is free software: you can redistribute it and/or modify
|
7
|
+
# it under the terms of the GNU Affero General Public License as published
|
8
|
+
# by the Free Software Foundation, either version 3 of the License, or
|
9
|
+
# (at your option) any later version.
|
10
|
+
#
|
11
|
+
# faildns is distributed in the hope that it will be useful,
|
12
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
13
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
14
|
+
# GNU Affero General Public License for more details.
|
15
|
+
#
|
16
|
+
# You should have received a copy of the GNU Affero General Public License
|
17
|
+
# along with faildns. If not, see <http://www.gnu.org/licenses/>.
|
18
|
+
#++
|
19
|
+
|
20
|
+
require 'faildns/resourcerecord/data'
|
21
|
+
require 'faildns/ip'
|
22
|
+
|
23
|
+
module DNS
|
24
|
+
|
25
|
+
class ResourceRecord
|
26
|
+
|
27
|
+
module IN
|
28
|
+
|
29
|
+
#--
|
30
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
31
|
+
# | ADDRESS |
|
32
|
+
# +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+
|
33
|
+
#
|
34
|
+
# where:
|
35
|
+
#
|
36
|
+
# ADDRESS A 32 bit Internet address.
|
37
|
+
#
|
38
|
+
# Hosts that have multiple Internet addresses will have multiple A
|
39
|
+
# records.
|
40
|
+
#
|
41
|
+
# A records cause no additional section processing. The RDATA section of
|
42
|
+
# an A line in a master file is an Internet address expressed as four
|
43
|
+
# decimal numbers separated by dots without any imbedded spaces (e.g.,
|
44
|
+
# "10.2.0.52" or "192.0.5.6").
|
45
|
+
#++
|
46
|
+
|
47
|
+
class A < Data
|
48
|
+
def self._parse (string, original)
|
49
|
+
A.new(IP.parse(string))
|
50
|
+
end
|
51
|
+
|
52
|
+
def self.length
|
53
|
+
4
|
54
|
+
end
|
55
|
+
|
56
|
+
attr_reader :ip
|
57
|
+
|
58
|
+
def initialize (what)
|
59
|
+
@ip = IP.new(what)
|
60
|
+
end
|
61
|
+
|
62
|
+
def pack
|
63
|
+
@ip.pack
|
64
|
+
end
|
65
|
+
|
66
|
+
def to_s
|
67
|
+
@ip.to_s
|
68
|
+
end
|
69
|
+
end
|
70
|
+
|
71
|
+
end
|
72
|
+
|
73
|
+
end
|
74
|
+
|
75
|
+
end
|