Module: DNSTraverse::MessageUtility
- Included in:
- DecodedQuery, Referral, Traverser
- Defined in:
- lib/dnstraverse/message_utility.rb
Class Method Summary collapse
- .msg_additional?(msg, args) ⇒ Boolean
- .msg_additional_ips?(msg, args) ⇒ Boolean
- .msg_answers?(msg, args) ⇒ Boolean
-
.msg_authority(msg) ⇒ Object
def msg_referrals(msg, args) r = msg.authority.select { |x| x.type.to_s.casecmp(‘NS’) == 0 && x.klass.to_s.casecmp(‘IN’) == 0 } if args then b = args r = r.select { |x| zonename = x.name.to_s if cond = zonename !~ /#@b$/i then Log.debug { “Excluding lame referral #b to #zonename” } raise “lame” end cond } end Log.debug { “Referrals: ” + r.map {|x| x.domainname.to_s }.join(“, ”) } return r end.
- .msg_cacheable(msg, bailiwick, type = :all) ⇒ Object
- .msg_comment(msg, args) ⇒ Object
-
.msg_follow_cnames(msg, args) ⇒ Object
follow any CNAMEs in the message and return the final name return nil if there is a loop.
- .msg_nodata?(msg) ⇒ Boolean
- .msg_validate(msg, args) ⇒ Object
Class Method Details
.msg_additional?(msg, args) ⇒ Boolean
81 82 83 84 85 86 87 88 89 90 91 92 |
# File 'lib/dnstraverse/message_utility.rb', line 81 def msg_additional?(msg, args) qclass = args[:qclass] || 'IN' Log.debug { "Looking for #{args[:qname]}/#{args[:qtype]} in additional" } add = msg.additional.select { |x| x.name.to_s.casecmp(args[:qname].to_s) == 0 && x.klass.to_s.casecmp(qclass.to_s) == 0 && x.type.to_s.casecmp(args[:qtype].to_s) == 0 } Log.debug { add.size > 0 ? "Found #{add.size} additional records" \ : "No additional records for #{args[:qname]}/#{args[:qtype]}"} return add.size > 0 ? add : nil end |
.msg_additional_ips?(msg, args) ⇒ Boolean
94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 |
# File 'lib/dnstraverse/message_utility.rb', line 94 def msg_additional_ips?(msg, args) qclass = args[:qclass] || 'IN' Log.debug { "Looking for #{args[:qname]}/#{args[:qtype]} in additional" } if add = msg.additional.select { |x| x.name.to_s.casecmp(args[:qname].to_s) == 0 && x.klass.to_s.casecmp(qclass.to_s) == 0 && x.type.to_s.casecmp(args[:qtype].to_s) == 0 } then ips = add.map {|x| x.address.to_s } Log.debug { "Found in additional #{args[:qname]} = " + ips.join(", ") } return ips end Log.debug { "No additional records for #{args[:qname]}/#{args[:qtype]}" } return nil end |
.msg_answers?(msg, args) ⇒ Boolean
67 68 69 70 71 72 73 74 75 76 77 78 79 |
# File 'lib/dnstraverse/message_utility.rb', line 67 def msg_answers?(msg, args) qname = args[:qname].to_s qclass = (args[:qclass] || 'IN').to_s qtype = args[:qtype].to_s any = qtype.casecmp('ANY') == 0 ? true : false ans = msg.answer.select { |x| x.name.to_s.casecmp(qname) == 0 && x.klass.to_s.casecmp(qclass) == 0 && (any || x.type.to_s.casecmp(qtype) == 0) } Log.debug { "Answers:" + ans.size.to_s} return ans.size > 0 ? ans : nil end |
.msg_authority(msg) ⇒ Object
def msg_referrals(msg, args)
r = msg.authority.select { |x|
x.type.to_s.casecmp('NS') == 0 && x.klass.to_s.casecmp('IN') == 0
}
if args[:bailiwick] then
b = args[:bailiwick]
r = r.select { |x|
zonename = x.name.to_s
if cond = zonename !~ /#{@b}$/i then
Log.debug { "Excluding lame referral #{b} to #{zonename}" }
raise "lame"
end
cond
}
end
Log.debug { "Referrals: " + r.map {|x| x.domainname.to_s }.join(", ") }
return r
end
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/dnstraverse/message_utility.rb', line 129 def (msg) ns = [] soa = [] other = [] for rr in msg. do type = rr.type.to_s klass = rr.klass.to_s if type.casecmp('NS') == 0 && klass.casecmp('IN') == 0 ns << rr elsif type.casecmp('SOA') == 0 && klass.casecmp('IN') == 0 soa << rr else other << rr end end return ns, soa, other end |
.msg_cacheable(msg, bailiwick, type = :all) ⇒ Object
184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 |
# File 'lib/dnstraverse/message_utility.rb', line 184 def msg_cacheable(msg, bailiwick, type = :all) good, bad, other = [], [], [] bw = bailiwick.to_s bwend = "." + bw for section in [:answer, :authority, :additional] do for rr in msg.send(section) do if rr.type.to_s == "OPT" then other << rr else name = rr.name.to_s if bailiwick.nil? or name.casecmp(bw) == 0 or name =~ /#{bwend}$/i then good << rr else bad << rr end end end end good.map {|x| Log.debug { "Records within bailiwick: " + x.to_s } } bad.map {|x| Log.debug { "Records outside bailiwick: " + x.to_s } } other.map {|x| Log.debug { "Other records discarded: " + x.to_s } } return good if type == :good return bad if type == :bad return good, bad, other end |
.msg_comment(msg, args) ⇒ Object
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 |
# File 'lib/dnstraverse/message_utility.rb', line 23 def msg_comment(msg, args) warnings = Array.new if args[:want_recursion] then if not msg.header.ra then warnings << "#{msg.answerfrom} doesn't allow recursion" end else if msg.header.ra then warnings << "#{msg.answerfrom} allows recursion" end end if msg.header.tc then warnings << "#{msg.answerfrom} sent truncated packet" end for warn in warnings do Log.warn { warn } end Log.debug { "#{msg.answerfrom} code #{msg.rcode}" } return warnings end |
.msg_follow_cnames(msg, args) ⇒ Object
follow any CNAMEs in the message and return the final name return nil if there is a loop
149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 |
# File 'lib/dnstraverse/message_utility.rb', line 149 def msg_follow_cnames(msg, args) name = args[:qname] type = args[:qtype] bw = args[:bailiwick].to_s bwend = ".#{args[:bailiwick]}" seen = {} while true do seen[name] = true return name if msg_answers?(msg, :qname => name, :qtype => type) if not ans = msg_answers?(msg, :qname => name, :qtype => 'CNAME') then return name end target = ans[0].domainname.to_s Log.debug { "CNAME encountered from #{name} to #{target}"} if name !~ /#{bwend}$/i then # target outside of bailiwick, don't follow any more CNAMEs. return target end name = target if seen[name] then Log.debug { "CNAME loop detected" } return nil end end end |
.msg_nodata?(msg) ⇒ Boolean
175 176 177 178 179 180 181 182 |
# File 'lib/dnstraverse/message_utility.rb', line 175 def msg_nodata?(msg) ns, soa, other = (msg) if soa.size > 0 or ns.size == 0 then Log.debug { "NODATA: soa=#{soa.size} ns=#{ns.size}" } return true end return false end |
.msg_validate(msg, args) ⇒ Object
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 |
# File 'lib/dnstraverse/message_utility.rb', line 44 def msg_validate(msg, args) a = args.dup a[:qclass]||= 'IN' return true if msg.rcode != Dnsruby::RCode.NOERROR begin if msg.question.size != 1 then raise ResolveError, "#{msg.answerfrom} returned unexpected " + "question size #{msg.question.size}" end for c in [:qname, :qclass, :qtype] do if a[c] and a[c].to_s.downcase != msg.question[0].send(c).to_s.downcase then raise ResolveError, "#{msg.answerfrom} returned mismatched #{c} " + "#{msg.question[0].send(c)} instead of expected #{a[c]}" end end rescue => e Log.debug { "Failed message was: " + msg.to_s } raise e end return true end |