faildns 0.0.1
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/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,95 @@
|
|
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
|
+
module DNS
|
21
|
+
|
22
|
+
class Header
|
23
|
+
|
24
|
+
#--
|
25
|
+
# OPCODE A four bit field that specifies kind of query in this
|
26
|
+
# message. This value is set by the originator of a query
|
27
|
+
# and copied into the response. The values are:
|
28
|
+
#
|
29
|
+
# 0 a standard query (QUERY)
|
30
|
+
#
|
31
|
+
# 1 an inverse query (IQUERY)
|
32
|
+
#
|
33
|
+
# 2 a server status request (STATUS)
|
34
|
+
#
|
35
|
+
# 3-15 reserved for future use
|
36
|
+
#++
|
37
|
+
|
38
|
+
class Opcode
|
39
|
+
Values = {
|
40
|
+
0 => :QUERY,
|
41
|
+
1 => :IQUERY,
|
42
|
+
2 => :STATUS,
|
43
|
+
3 => :RESERVED3,
|
44
|
+
4 => :NOTIFY,
|
45
|
+
5 => :UPDATE,
|
46
|
+
6 => :RESERVED6,
|
47
|
+
7 => :RESERVED7,
|
48
|
+
8 => :RESERVED8,
|
49
|
+
9 => :RESERVED9,
|
50
|
+
10 => :RESERVED10,
|
51
|
+
11 => :RESERVED11,
|
52
|
+
12 => :RESERVED12,
|
53
|
+
13 => :RESERVED13,
|
54
|
+
14 => :RESERVED14,
|
55
|
+
15 => :RESERVED15
|
56
|
+
}
|
57
|
+
|
58
|
+
attr_reader :value
|
59
|
+
|
60
|
+
def initialize (value)
|
61
|
+
if value.is_a? Symbol
|
62
|
+
@value = Values.find {|key, val| val == value}.first rescue nil
|
63
|
+
elsif value.is_a? Integer
|
64
|
+
@value = value
|
65
|
+
else
|
66
|
+
@value = value.value rescue nil
|
67
|
+
end
|
68
|
+
|
69
|
+
if !self.to_sym
|
70
|
+
raise ArgumentError.new('The passed value is not a suitable type.')
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def == (what)
|
75
|
+
if what.is_a? Symbol
|
76
|
+
self.to_sym == what
|
77
|
+
elsif value.is_a? Integer
|
78
|
+
@value == what
|
79
|
+
else
|
80
|
+
@value == what.value rescue false
|
81
|
+
end
|
82
|
+
end
|
83
|
+
|
84
|
+
def to_sym
|
85
|
+
Values[@value]
|
86
|
+
end
|
87
|
+
|
88
|
+
def to_s
|
89
|
+
Values[@value].to_s
|
90
|
+
end
|
91
|
+
end
|
92
|
+
|
93
|
+
end
|
94
|
+
|
95
|
+
end
|
@@ -0,0 +1,123 @@
|
|
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
|
+
module DNS
|
21
|
+
|
22
|
+
class Header
|
23
|
+
|
24
|
+
#--
|
25
|
+
# RCODE Response code - this 4 bit field is set as part of
|
26
|
+
# responses. The values have the following
|
27
|
+
# interpretation:
|
28
|
+
#
|
29
|
+
# 0 No error condition
|
30
|
+
#
|
31
|
+
# 1 Format error - The name server was
|
32
|
+
# unable to interpret the query.
|
33
|
+
#
|
34
|
+
# 2 Server failure - The name server was
|
35
|
+
# unable to process this query due to a
|
36
|
+
# problem with the name server.
|
37
|
+
#
|
38
|
+
# 3 Name Error - Meaningful only for
|
39
|
+
# responses from an authoritative name
|
40
|
+
# server, this code signifies that the
|
41
|
+
# domain name referenced in the query does
|
42
|
+
# not exist.
|
43
|
+
#
|
44
|
+
# 4 Not Implemented - The name server does
|
45
|
+
# not support the requested kind of query.
|
46
|
+
#
|
47
|
+
# 5 Refused - The name server refuses to
|
48
|
+
# perform the specified operation for
|
49
|
+
# policy reasons. For example, a name
|
50
|
+
# server may not wish to provide the
|
51
|
+
# information to the particular requester,
|
52
|
+
# or a name server may not wish to perform
|
53
|
+
# a particular operation (e.g., zone
|
54
|
+
# transfer) for particular data.
|
55
|
+
#
|
56
|
+
# 6-15 Reserved for future use.
|
57
|
+
#++
|
58
|
+
|
59
|
+
class Status
|
60
|
+
Values = {
|
61
|
+
0 => :NOERROR,
|
62
|
+
1 => :FORMERR,
|
63
|
+
2 => :SERVFAIL,
|
64
|
+
3 => :NXDOMAIN,
|
65
|
+
4 => :NOTIMP,
|
66
|
+
5 => :REFUSED,
|
67
|
+
6 => :YXDOMAIN,
|
68
|
+
7 => :YXRRSET,
|
69
|
+
8 => :NXRRSET,
|
70
|
+
9 => :NOTAUTH,
|
71
|
+
10 => :NOTZONE,
|
72
|
+
11 => :RESERVED11,
|
73
|
+
12 => :RESERVED12,
|
74
|
+
13 => :RESERVED13,
|
75
|
+
14 => :RESERVED14,
|
76
|
+
15 => :RESERVED15,
|
77
|
+
16 => :BADSIG,
|
78
|
+
17 => :BADKEY,
|
79
|
+
18 => :BADTIME,
|
80
|
+
19 => :BADMODE,
|
81
|
+
20 => :BADNAME,
|
82
|
+
21 => :BADALG,
|
83
|
+
22 => :BADTRUNC
|
84
|
+
}
|
85
|
+
|
86
|
+
attr_reader :value
|
87
|
+
|
88
|
+
def initialize (value)
|
89
|
+
if value.is_a? Symbol
|
90
|
+
@value = Values.find {|key, val| val == value}.first rescue nil
|
91
|
+
elsif value.is_a? Integer
|
92
|
+
@value = value
|
93
|
+
else
|
94
|
+
@value = value.value rescue nil
|
95
|
+
end
|
96
|
+
|
97
|
+
if !self.to_sym
|
98
|
+
raise ArgumentError.new('The passed value is not a suitable type.')
|
99
|
+
end
|
100
|
+
end
|
101
|
+
|
102
|
+
def == (what)
|
103
|
+
if what.is_a? Symbol
|
104
|
+
self.to_sym == what
|
105
|
+
elsif value.is_a? Integer
|
106
|
+
@value == what
|
107
|
+
else
|
108
|
+
@value == what.value rescue false
|
109
|
+
end
|
110
|
+
end
|
111
|
+
|
112
|
+
def to_sym
|
113
|
+
Values[@value]
|
114
|
+
end
|
115
|
+
|
116
|
+
def to_s
|
117
|
+
Values[@value].to_s
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
121
|
+
end
|
122
|
+
|
123
|
+
end
|
@@ -0,0 +1,72 @@
|
|
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
|
+
module DNS
|
21
|
+
|
22
|
+
class Header
|
23
|
+
|
24
|
+
#--
|
25
|
+
# QR A one bit field that specifies whether this message is a
|
26
|
+
# query (0), or a response (1).
|
27
|
+
#++
|
28
|
+
|
29
|
+
class Type
|
30
|
+
Values = {
|
31
|
+
0 => :QUERY,
|
32
|
+
1 => :RESPONSE
|
33
|
+
}
|
34
|
+
|
35
|
+
attr_reader :value
|
36
|
+
|
37
|
+
def initialize (value)
|
38
|
+
if value.is_a? Symbol
|
39
|
+
@value = Values.find {|key, val| val == value}.first rescue nil
|
40
|
+
elsif value.is_a? Integer
|
41
|
+
@value = value
|
42
|
+
else
|
43
|
+
@value = value.value rescue nil
|
44
|
+
end
|
45
|
+
|
46
|
+
if !self.to_sym
|
47
|
+
raise ArgumentError.new('The passed value is not a suitable type.')
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
def == (what)
|
52
|
+
if what.is_a? Symbol
|
53
|
+
self.to_sym == what
|
54
|
+
elsif value.is_a? Integer
|
55
|
+
@value == what
|
56
|
+
else
|
57
|
+
@value == what.value rescue false
|
58
|
+
end
|
59
|
+
end
|
60
|
+
|
61
|
+
def to_sym
|
62
|
+
Values[@value]
|
63
|
+
end
|
64
|
+
|
65
|
+
def to_s
|
66
|
+
Values[@value].to_s
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
end
|
71
|
+
|
72
|
+
end
|
data/lib/faildns/ip.rb
ADDED
@@ -0,0 +1,57 @@
|
|
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 'ipaddr'
|
21
|
+
|
22
|
+
module DNS
|
23
|
+
|
24
|
+
class IP
|
25
|
+
def self.parse (string)
|
26
|
+
return IP.new(IPAddr.new_ntoh(string))
|
27
|
+
end
|
28
|
+
|
29
|
+
attr_reader :version, :ip
|
30
|
+
|
31
|
+
def initialize (what)
|
32
|
+
if what.is_a?(String)
|
33
|
+
@ip = IPAddr.new(what.to_s)
|
34
|
+
elsif what.is_a?(IP)
|
35
|
+
@ip = what.ip
|
36
|
+
elsif what.is_a?(IPAddr)
|
37
|
+
@ip = what
|
38
|
+
else
|
39
|
+
DNS.debug what.inspect
|
40
|
+
raise ArgumentError.new 'wat is dis i dont even'
|
41
|
+
end
|
42
|
+
|
43
|
+
@version = (@ip.ipv4?) ? 4 : 6
|
44
|
+
end
|
45
|
+
|
46
|
+
def pack
|
47
|
+
@ip.hton
|
48
|
+
end
|
49
|
+
|
50
|
+
def to_s
|
51
|
+
@ip.to_s
|
52
|
+
end
|
53
|
+
|
54
|
+
alias to_str to_s
|
55
|
+
end
|
56
|
+
|
57
|
+
end
|
@@ -0,0 +1,100 @@
|
|
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/common'
|
21
|
+
require 'faildns/header'
|
22
|
+
require 'faildns/question'
|
23
|
+
require 'faildns/resourcerecord'
|
24
|
+
|
25
|
+
module DNS
|
26
|
+
|
27
|
+
class Message
|
28
|
+
def self.parse (string)
|
29
|
+
string.force_encoding 'BINARY'
|
30
|
+
original = string.clone
|
31
|
+
|
32
|
+
header = Header.parse(string);
|
33
|
+
|
34
|
+
questions = []
|
35
|
+
1.upto(header.questions) {
|
36
|
+
questions << Question.parse(string, original);
|
37
|
+
}
|
38
|
+
|
39
|
+
answers = []
|
40
|
+
1.upto(header.answers) {
|
41
|
+
answers << ResourceRecord.parse(string, original);
|
42
|
+
}
|
43
|
+
|
44
|
+
authorities = []
|
45
|
+
1.upto(header.authorities) {
|
46
|
+
authorities << ResourceRecord.parse(string, original);
|
47
|
+
}
|
48
|
+
|
49
|
+
additionals = []
|
50
|
+
1.upto(header.additionals) {
|
51
|
+
additionals << ResourceRecord.parse(string, original);
|
52
|
+
}
|
53
|
+
|
54
|
+
Message.new(header, questions, answers, authorities, additionals)
|
55
|
+
end
|
56
|
+
|
57
|
+
def self.length (string)
|
58
|
+
string = string.clone
|
59
|
+
end
|
60
|
+
|
61
|
+
attr_reader :header, :questions, :answers, :authorities, :additionals
|
62
|
+
|
63
|
+
def initialize (*args)
|
64
|
+
if args.length > 1
|
65
|
+
@header, @questions, @answers, @authorities, @additionals = *(args.concat([[], [], [], []]))
|
66
|
+
else
|
67
|
+
raise ArgumentError.new('You have to pass at least 1 parameter.')
|
68
|
+
end
|
69
|
+
|
70
|
+
if block_given?
|
71
|
+
yield self
|
72
|
+
end
|
73
|
+
end
|
74
|
+
|
75
|
+
def pack
|
76
|
+
result = ''
|
77
|
+
|
78
|
+
result += @header.pack
|
79
|
+
|
80
|
+
@questions.each {|question|
|
81
|
+
result += question.pack
|
82
|
+
}
|
83
|
+
|
84
|
+
@answers.each {|answer|
|
85
|
+
result += answer.pack
|
86
|
+
}
|
87
|
+
|
88
|
+
@authorities.each {|authority|
|
89
|
+
result += answer.pack
|
90
|
+
}
|
91
|
+
|
92
|
+
@additionals.each {|additional|
|
93
|
+
result += additional.pack
|
94
|
+
}
|
95
|
+
|
96
|
+
return result
|
97
|
+
end
|
98
|
+
end
|
99
|
+
|
100
|
+
end
|