class PassiveDNS::PDNSToolState
holds state in memory of the queue to be queried, records returned, and the level of recursion
Attributes
:debug enables verbose logging to standard output
:level is the recursion depth
Public Class Methods
creates a new, blank PDNSToolState
instance
# File lib/passivedns/client/state.rb, line 17 def initialize @queue = [] @recs = [] @level = 0 end
Public Instance Methods
adding a query to the queue of things to be queried, but only if the query isn't already queued or answered
# File lib/passivedns/client/state.rb, line 59 def add_query(query,state,level=@level+1) if query =~ /^\d+ \w+\./ query = query.split(/ /,2)[1] end return if get_state(query) puts "Adding query: #{query}, #{state}, #{level}" if @debug @queue << PDNSQueueEntry.new(query,state,level) end
adds the record to the list of records received and tries to add the answer and query back to the queue for future query
# File lib/passivedns/client/state.rb, line 31 def add_result(res) @recs << res add_query(res.answer,'pending') add_query(res.query,'pending') end
returns each query waiting on the queue
# File lib/passivedns/client/state.rb, line 69 def each_query(max_level=20) @queue.each do |q| if q.state == 'pending' or q.state == 'failed' @level = q.level q.state = 'queried' if q.level < max_level yield q.query end end end end
returns the state of a provided query
# File lib/passivedns/client/state.rb, line 49 def get_state(query) @queue.each do |q| if q.query == query return q.state end end false end
returns the next record
# File lib/passivedns/client/state.rb, line 24 def next_result @recs.each do |rec| yield rec end end
transforms a set of results into GDF syntax
# File lib/passivedns/client/state.rb, line 82 def to_gdf output = "nodedef> name,description VARCHAR(12),color,style\n" # IP "$node2,,white,1" # domain "$node2,,gray,2" # Struct.new(:query, :answer, :rrtype, :ttl, :firstseen, :lastseen) colors = {"MX" => "green", "A" => "blue", "CNAME" => "pink", "NS" => "red", "SOA" => "white", "PTR" => "purple", "TXT" => "brown"} nodes = {} edges = {} next_result do |i| if i nodes[i.query + ",,gray,2"] = true if i.answer =~ /[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}/ then nodes[i.answer + ",,white,1"] = true else nodes[i.answer + ",,gray,2"] = true end color = colors[i.rrtype] color ||= "blue" edges[i.query + "," + i.answer + "," + color] = true end end nodes.each do |i,j| output += i+"\n" end output += "edgedef> node1,node2,color\n" edges.each do |i,j| output += i+"\n" end output end
transforms a set of results into graphml syntax
# File lib/passivedns/client/state.rb, line 136 def to_graphml output = '<?xml version="1.0" encoding="UTF-8"?> <graphml xmlns="http://graphml.graphdrawing.org/xmlns" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://graphml.graphdrawing.org/xmlns http://graphml.graphdrawing.org/xmlns/1.0/graphml.xsd"> <graph id="G" edgedefault="directed"> ' nodes = {} edges = {} next_result do |r| if r output += " <node id='#{r.query}'/>\n" unless nodes["#{r.query}"] nodes[r.query] = true output += " <node id='#{r.answer}'/>\n" unless nodes["#{r.answer}"] nodes[r.answer] = true output += " <edge source='#{r.query}' target='#{r.answer}'/>\n" unless edges["#{r.query}|#{r.answer}"] end end output += '</graph></graphml>'+"\n" end
transforms a set of results into graphviz syntax
# File lib/passivedns/client/state.rb, line 114 def to_graphviz colors = {"MX" => "green", "A" => "blue", "CNAME" => "pink", "NS" => "red", "SOA" => "white", "PTR" => "purple", "TXT" => "brown"} output = "graph pdns {\n" nodes = {} next_result do |l| if l unless nodes[l.query] output += " \"#{l.query}\" [shape=ellipse, style=filled, color=gray];\n" if l.answer =~ /^\d{3}\.\d{3}\.\d{3}\.\d{3}$/ output += " \"#{l.answer}\" [shape=box, style=filled, color=white];\n" else output += " \"#{l.answer}\" [shape=ellipse, style=filled, color=gray];\n" end nodes[l.query] = true end output += " \"#{l.query}\" -- \"#{l.answer}\" [color=#{colors[l.rrtype]}];\n" end end output += "}\n" end
transforms a set of results into JSON
# File lib/passivedns/client/state.rb, line 180 def to_json output = "[\n" sep = "" next_result do |rec| output += sep output += rec.to_json sep = ",\n" end output += "\n]\n" end
transforms a set of results into a text string
# File lib/passivedns/client/state.rb, line 192 def to_s(sep="\t") output = "" next_result do |rec| output += rec.to_s(sep)+"\n" end output end
transforms a set of results into XML
# File lib/passivedns/client/state.rb, line 159 def to_xml output = '<?xml version="1.0" encoding="UTF-8" ?>'+"\n" output += "<report>\n" output += " <results>\n" next_result do |rec| output += " "+rec.to_xml+"\n" end output += " </results>\n" output += "</report>\n" end
transforms a set of results into YAML
# File lib/passivedns/client/state.rb, line 171 def to_yaml output = "" next_result do |rec| output += rec.to_yaml+"\n" end output end
sets the state of a given query
# File lib/passivedns/client/state.rb, line 38 def update_query(query,state) @queue.each do |q| if q.query == query puts "update_query: #{query} (#{q.state}) -> (#{state})" if @debug q.state = state break end end end