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,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
|