Class: Probe::Util

Inherits:
Object
  • Object
show all
Defined in:
lib/domain-probe/util.rb

Overview

Utility functions to assist domain-probing

Class Method Summary collapse

Class Method Details

.append_trailing_dot_if_necessary(domain) ⇒ Object

if the domain is not ended with dot, then append one



106
107
108
109
# File 'lib/domain-probe/util.rb', line 106

def self.append_trailing_dot_if_necessary domain
   return domain if !domain || domain.end_with?(".")
   domain + "."
end

.detect_nameservers(zone) ⇒ Object

Detect the nameservers against specific zone



42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
# File 'lib/domain-probe/util.rb', line 42

def self.detect_nameservers zone
  return [] if !zone
  zone = append_trailing_dot_if_necessary zone
  
  nameserver_ips = []
  nameserver_names = []
  begin
    resolver = Net::DNS::Resolver.new(:udp_timeout => 2)
    resolver.log_level = Net::DNS::ERROR
    packet = resolver.query(zone, Net::DNS::NS)
    packet.answer.each { |record|
        next unless record.name == append_trailing_dot_if_necessary(zone) && record.type == "NS"
        nameserver_names << record.nsdname
        packet.additional.select{ |x| x.name == record.nsdname && x.type == "A" }.each{ |rr|
            nameserver_ips << rr.address.to_s
        }
    } if packet && !packet.header.error? && packet.answer
    
    if nameserver_ips.empty? 
      nameserver_ips += resolve_addresses(nameserver_names)
    end
  rescue  => ex
    puts "#{ex.class} happened: #{ex.message} while detecting nameservers of #{zone}\n"
  end
  
  nameserver_ips
end

.detect_zone(domain) ⇒ Object

Detect the zone name the specific domain belongs to



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
# File 'lib/domain-probe/util.rb', line 11

def self.detect_zone domain
  
  return nil if !domain
  domain = append_trailing_dot_if_necessary domain
  names = domain.split "."
  
  zone = nil
  begin
    names.size.times { |index|
      resolver = Net::DNS::Resolver.new(:udp_timeout => 2)
      resolver.log_level = Net::DNS::ERROR
      packet = resolver.query(domain, Net::DNS::SOA)
      packet.answer.each { |record|
          next unless record.name == domain && record.type == "SOA"
          zone = domain
          break
      } if packet && !packet.header.error? && packet.answer
    
      return remove_trailing_dot_if_any(zone) unless !zone
      domain = domain.slice(names[index].length + 1,domain.length - names[index].length - 1)
    } 
  rescue  => ex
    puts "#{ex.class} happened: #{ex.message} while detecting zone of #{domain}\n"
  end
  
  zone
end

.is_subdomain?(domain, zone) ⇒ Boolean

to judge whether the domain is a subdomain of zone.

Returns:

  • (Boolean)


122
123
124
125
126
127
# File 'lib/domain-probe/util.rb', line 122

def self.is_subdomain?(domain,zone)
  return false if !domain || !zone
  zone_with_trailing_dot = Util.append_trailing_dot_if_necessary(zone)
  return false if domain == zone_with_trailing_dot
  domain.end_with?(zone_with_trailing_dot) && domain[domain.index(zone_with_trailing_dot) - 1,1] == "."
end

.organize_authorities(authorities, additional) ⇒ Object

Organize the authorities to assist recusive queries



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
# File 'lib/domain-probe/util.rb', line 73

def self.organize_authorities(authorities,additional)
  
  return [] if !authorities
  nameserver_ips = []
  nameserver_names = []
  authorities.each{ |authority|
    next unless authority.type == "NS"
    nameserver_names << authority.nsdname
    additional.select{ |x| x.name == authority.nsdname && x.type == "A" }.each{ |rr|
        nameserver_ips << rr.address.to_s
    }
  }
     
  if nameserver_ips.empty? 
    nameserver_ips += resolve_addresses(nameserver_names)
  end
  
  nameserver_ips
end

.polish_url(domain) ⇒ Object



96
97
98
99
100
# File 'lib/domain-probe/util.rb', line 96

def self.polish_url(domain)
  return nil if !domain
  zone = detect_zone domain
 "http://" + (!zone || domain.start_with?(WWW_PREFIX) ? domain : WWW_PREFIX + zone)
end

.remove_trailing_dot_if_any(domain) ⇒ Object

removing trailing dot, if there is one



114
115
116
117
# File 'lib/domain-probe/util.rb', line 114

def self.remove_trailing_dot_if_any domain
   return domain.chop if domain && domain.end_with?(".")
   domain
end

.resolve_addresses(names) ⇒ Object

resolve the names to ip addresses



132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/domain-probe/util.rb', line 132

def self.resolve_addresses names
  
  return [] unless names && !names.empty?
  addresses = []
  begin
      resolver = Net::DNS::Resolver.new(:udp_timeout => 2)
      resolver.log_level = Net::DNS::ERROR
      names.each{ |name|
          packet = resolver.query(name, Net::DNS::A)
          next unless packet && !packet.header.error?
          packet.answer.each { |record|
              next unless record.type == "A"
              addresses << record.address.to_s
          }
      }
  rescue  => ex
    puts "#{ex.class} happened: #{ex.message} while resolving address of one of #{names.join(',')}\n"
  end
  addresses
end