class Wmap::CidrTracker

Class to track host/IP to the known (trusted) network CIDR blocks

Attributes

cidr_seeds[RW]
data_dir[RW]
known_cidr_blks[RW]
verbose[RW]

Public Class Methods

new(params = {}) click to toggle source

Set class default variables

# File lib/wmap/cidr_tracker.rb, line 17
def initialize (params = {})
        @verbose=params.fetch(:verbose, false)
        @data_dir=params.fetch(:data_dir, File.dirname(__FILE__)+'/../../data/')
        Dir.mkdir(@data_dir) unless Dir.exist?(@data_dir)
        @cidr_seeds=params.fetch(:cidr_seeds, @data_dir + '/' + 'cidrs')
        File.write(@cidr_seeds, "") unless File.exist?(@cidr_seeds)
        load_cidr_blks_from_file(@cidr_seeds)
end

Public Instance Methods

add(cidr,ref=nil,netname=nil) click to toggle source

'setter' to add an entry to CIDR store @known_cidr_blks

# File lib/wmap/cidr_tracker.rb, line 75
def add (cidr,ref=nil,netname=nil)
        puts "Load the entry into the CIDR store: #{cidr}"
        raise "Unknown CIDR format: #{cidr}" unless is_cidr?(cidr)
        # Obtain the 'ref' and 'netname' value automatically in case not passed as method parameters
        if ref.nil? or netname.nil?
                whois = Wmap::Whois.new
                # Note 11/1/2014: Use IP instead of the CIDR to perform the query, as the current ruby-whois query does not support CIDR as query input
                ip=cidr.split("/")[0]
                ref=whois.get_net_desc(ip)
                netname=whois.get_netname(ip)
                whois=nil
        end
        @known_cidr_blks = Hash.new unless @known_cidr_blks
        if @known_cidr_blks.key?(cidr)
                puts "Skip! Entry is already exist: #{cidr}"
                return nil
        else
                @known_cidr_blks[cidr] = Hash.new
                @known_cidr_blks[cidr]['ref']=ref
                @known_cidr_blks[cidr]['netname']=netname
                puts "Entry loaded!"
        end
        # Re-sort the blocks in order for better performance
        #@known_cidr_blks_desc_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>true)
        #@known_cidr_blks_asce_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>false)
        @known_cidr_blks_asce_index=@known_cidr_blks.keys.sort
        @known_cidr_blks_desc_index=@known_cidr_blks_asce_index.reverse
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" # if @verbose
end
cidr_known?(cidr) click to toggle source

Determine if a CIDR entry is already known

# File lib/wmap/cidr_tracker.rb, line 198
def cidr_known? (cidr)
        puts "Determine if the CIDR is known: #{cidr}" if @verbose
        known=false
        cidr=cidr.strip unless cidr.nil?
        cidr=cidr+"/32" if is_ip?(cidr)
        raise "Invalid CIDR format: #{cidr}" unless is_cidr?(cidr)
        return false if @known_cidr_blks==nil
        return true if @known_cidr_blks.key?(cidr)
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" if @verbose
        return false
end
Also aliased as: is_known?
cidr_lookup(ip) click to toggle source

Return the matching CIDR block for a ip

# File lib/wmap/cidr_tracker.rb, line 178
def cidr_lookup (ip)
        puts "Lookup the CIDR name from the known CIDR list for the IP: #{ip}" if @verbose
        return nil if @known_cidr_blks==nil
        puts "CIDR Lookup: #{ip} ..." if @verbose
        @known_cidr_blks_desc_index.each do |line|
                first_octet_ip = ip.split('.').first.to_i
                first_octet_blk = line.split('.').first.to_i
                next if first_octet_blk > first_octet_ip
                cidr4 = NetAddr::CIDR.create(line)
                known = cidr4.contains?(ip+'/32')
                return line if known
        end
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" if @verbose
        return nil
end
Also aliased as: lookup, query
cidr_trusted?(cidr) click to toggle source

Determine if a cidr is within the range of our known network CIDR blocks

# File lib/wmap/cidr_tracker.rb, line 213
def cidr_trusted? (cidr)
        puts "Determine if the CIDR within our ranges: #{cidr}" if @verbose
        trusted=false
        cidr=cidr.strip unless cidr.nil?
        cidr=cidr+"/32" if is_ip?(cidr)
        raise "Invalid CIDR format: #{cidr}" unless is_cidr?(cidr)
        return false if @known_cidr_blks==nil
        return true if @known_cidr_blks.key?(cidr)
        @known_cidr_blks_asce_index.each do |line|
                cidr4 = NetAddr::CIDR.create(line)
                return true if cidr4.contains?(cidr)
        end
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" if @verbose
        return false
end
Also aliased as: is_trusted?
cidr_worker(host) click to toggle source

Main worker method to retrieve known network information for a host / ip

# File lib/wmap/cidr_tracker.rb, line 27
def cidr_worker (host)
        puts "Starting tracking of known CIDR information for host: #{host}" if @verbose
        host=host.strip.downcase
        ip=host_2_ip(host)
        cidr=cidr_lookup(ip)
        ref=get_cidr_ref(cidr)
        netname=get_cidr_netname(cidr)
        # save the data
        tracker=Hash.new
        tracker['host']=host
        tracker['ip']=ip
        tracker['cidr']=cidr
        tracker['ref']=ref
        tracker['netname']=netname
        return tracker
rescue => ee
        puts "Exception on method #{__method__} for host #{host}: #{ee}" # if @verbose
        return nil
end
Also aliased as: track
count() click to toggle source

Count numbers of CIDR object entries in the CIDR cache table

# File lib/wmap/cidr_tracker.rb, line 129
def count
        puts "Counting number of entries in the CIDR cache table ..." if @verbose
        cnt=0
        @known_cidr_blks.keys.map do |key|
                if is_cidr?(key)
                        cnt=cnt+1
                end
        end
        puts "Current number of CIDR object entries: #{cnt}" if @verbose
        return cnt
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" if @verbose
end
counts() click to toggle source

Count numbers of IPs within the trusted CIDR objects

# File lib/wmap/cidr_tracker.rb, line 144
def counts
        puts "Counting number of IPs within the CIDR store:" if @verbose
        cnt=0
        @known_cidr_blks.keys.map do |key|
                cnt=cnt+size(key)
        end
        puts "Total number of trusted IPs: #{cnt}" if @verbose
        return cnt
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" if @verbose
end
del(cidr,ref=nil,netname=nil)
Alias for: delete
delete(cidr,ref=nil,netname=nil) click to toggle source

'setter' to remove an entry to CIDR store @known_cidr_blks

# File lib/wmap/cidr_tracker.rb, line 107
def delete (cidr,ref=nil,netname=nil)
        puts "Remove the entry from the CIDR store: #{cidr}"
        #cidr.strip!
        raise "Unknown CIDR format: #{cidr}" unless is_cidr?(cidr)
        if @known_cidr_blks.key?(cidr)
                puts "Deleting ..."
                @known_cidr_blks.delete(cidr)
                puts "Entry cleared!"
        else
                raise "Unknown CIDR entry: #{cidr}"
        end
        # Re-sort the blocks in order for better performance
        #@known_cidr_blks_desc_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>true)
        #@known_cidr_blks_asce_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>false)
        @known_cidr_blks_asce_index=@known_cidr_blks.keys.sort
        @known_cidr_blks_desc_index=@known_cidr_blks_asce_index.reverse
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" # if @verbose
end
Also aliased as: del
get_cidr_netname(cidr) click to toggle source

Retrieve the CIDR netname field for tracking purpose, if it's a known CIDR entry

# File lib/wmap/cidr_tracker.rb, line 251
def get_cidr_netname (cidr)
        puts "Lookup CIDR block #{cidr} netname ..." if @verbose
        cidr=cidr.strip unless cidr.nil?
        return nil unless @known_cidr_blks.key?(cidr)
        return @known_cidr_blks[cidr]['netname']
end
get_cidr_ref(cidr) click to toggle source

Retrieve the CIDR reference text for tracking purpose, if it's a known CIDR entry

# File lib/wmap/cidr_tracker.rb, line 243
def get_cidr_ref (cidr)
        puts "Lookup CIDR block #{cidr} reference text ..." if @verbose
        cidr=cidr.strip unless cidr.nil?
        return nil unless @known_cidr_blks.key?(cidr)
        return @known_cidr_blks[cidr]['ref']
end
inspect()
ip_trusted?(ip) click to toggle source

Check if the specific IP within the range of a list of known CIDR blocks

# File lib/wmap/cidr_tracker.rb, line 157
def ip_trusted? (ip)
        puts "Check if the IP within the range of the known CIDR blocks: #{ip}" if @verbose
        known = false
        return false if @known_cidr_blks==nil
        first_octet_ip = ip.split('.').first.to_i
        @known_cidr_blks_desc_index.each do |line|
                first_octet_blk = line.split('.').first.to_i
                next if first_octet_blk > first_octet_ip
                puts "line: #{line}" if @verbose
                cidr4 = NetAddr::CIDR.create(line)
                known = cidr4.contains?(ip+'/32')
                break if known
        end
        return known
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" if @verbose
        return false
end
Also aliased as: is_trusted?
is_known?(cidr)
Alias for: cidr_known?
is_trusted?(ip)
Alias for: ip_trusted?
load_cidr_blks_from_file(file_cidrs=@cidr_seeds) click to toggle source

'setter' to load the known CIDR blocks into an instance variable @known_cidr_blks

# File lib/wmap/cidr_tracker.rb, line 49
def load_cidr_blks_from_file(file_cidrs=@cidr_seeds)
        puts "Load the known CIDR seed file: #{file_cidrs}" if @verbose
        f=File.open(file_cidrs, 'r')
        f.each do |line|
                entry=line.chomp.split(',')
                next unless is_cidr?(entry[0])
                puts "Loading: #{entry[0]}" if @verbose
                key=entry[0].strip
                @known_cidr_blks = Hash.new unless @known_cidr_blks
                @known_cidr_blks[key] = Hash.new if not @known_cidr_blks.key?(key)
                @known_cidr_blks[key]['ref']=entry[1].nil? ? nil : entry[1].strip
                @known_cidr_blks[key]['netname']=entry[2].nil? ? nil : entry[2].strip
        end
        f.close
        # Sort the blocks in order once for better performance. Update 10/29/2018 to support Netaddr 2.x syntax
        #@known_cidr_blks_desc_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>true)
        #@known_cidr_blks_asce_index=NetAddr.sort(@known_cidr_blks.keys, :Desc=>false)
        if @known_cidr_blks
                @known_cidr_blks_asce_index=@known_cidr_blks.keys.sort
                @known_cidr_blks_desc_index=@known_cidr_blks_asce_index.reverse
        end
#rescue => ee
#      puts "Exception on method #{__method__}: #{ee}" # if @verbose
end
lookup(ip)
Alias for: cidr_lookup
print()
print_known_cidr_blks() click to toggle source

Print summary report of a list of known CIDR blocks

Also aliased as: inspect
print_known_cidr_blks_asce() click to toggle source

Print summary report of a list of known CIDR blocks in the ascendant order

Also aliased as: print
print_known_cidr_blks_desc() click to toggle source

Print summary report of a list of known CIDR blocks in the descendant order

query(ip)
Alias for: cidr_lookup
save!(file_cidrs=@cidr_seeds)
Alias for: save_cidrs_to_file!
save_cidrs_to_file!(file_cidrs=@cidr_seeds) click to toggle source

Save the current cidr hash table into a file

# File lib/wmap/cidr_tracker.rb, line 259
def save_cidrs_to_file!(file_cidrs=@cidr_seeds)
        puts "Saving the current cidrs cache table from memory to file: #{file_cidrs} ..." if @verbose
        timestamp=Time.now
        f=File.open(file_cidrs, 'w')
        f.write "# Local cidrs file created by Wmap::CidrTracker.save method at: #{timestamp}\n"
        f.write "Network CIDR, CIDR RIPE Reference Text, CIDR NETNAME\n"
        @known_cidr_blks_asce_index.map do |key|
                ref=get_cidr_ref(key)
                netname=get_cidr_netname(key)
                f.write "#{key},#{ref},#{netname}\n"
        end
        f.close
        puts "CIDR cache table is successfully saved: #{file_cidrs}"
#rescue => ee
#      puts "Exception on method #{__method__}: #{ee}" if @verbose
end
Also aliased as: save!
size(cidr) click to toggle source

NetAddr wrapper to determine number of IPs within the CIDR object.

# File lib/wmap/cidr_tracker.rb, line 232
def size (cidr)
        puts "Determine the size of CIDR object: #{cidr}" if @verbose
        raise "Invalid CIDR format: #{cidr}" unless is_cidr?(cidr)
        obj = NetAddr::CIDR.create(cidr)
        return obj.size.to_i
rescue => ee
        puts "Exception on method #{__method__}: #{ee}" if @verbose
        return nil
end
track(host)
Alias for: cidr_worker