class PassiveDNS::PDNSToolState

holds state in memory of the queue to be queried, records returned, and the level of recursion

Attributes

debug[RW]

:debug enables verbose logging to standard output

level[R]

:level is the recursion depth

Public Class Methods

new() click to toggle source

creates a new, blank PDNSToolState instance

# File lib/passivedns/client/state.rb, line 17
def initialize
  @queue = []
  @recs = []
  @level = 0
end

Public Instance Methods

add_query(query,state,level=@level+1) click to toggle source

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
add_result(res) click to toggle source

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
each_query(max_level=20) { |query| ... } click to toggle source

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
get_state(query) click to toggle source

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
next_result() { |rec| ... } click to toggle source

returns the next record

# File lib/passivedns/client/state.rb, line 24
def next_result
  @recs.each do |rec|
    yield rec
  end
end
to_gdf() click to toggle source

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
to_graphml() click to toggle source

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
to_graphviz() click to toggle source

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
to_json() click to toggle source

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
to_s(sep="\t") click to toggle source

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
to_xml() click to toggle source

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
to_yaml() click to toggle source

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
update_query(query,state) click to toggle source

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