Class: IpToAsn::Lookup
- Inherits:
-
Object
- Object
- IpToAsn::Lookup
- Defined in:
- lib/iptoasn/iptoasn.rb
Instance Method Summary collapse
- #as_name(name_offset, name_length) ⇒ Object
- #country(country_index) ⇒ Object
- #find_range(ranges:, ip_address:) ⇒ Object
-
#initialize(db_ip2asn: nil, db_country: nil, db_names: nil) ⇒ Lookup
constructor
rubocop:disable Metrics/AbcSize.
- #ip_to_int(ip) ⇒ Object
- #lookup(ip) ⇒ Object
-
#search_db(ip) ⇒ Object
rubocop:disable Metrics/AbcSize.
Constructor Details
#initialize(db_ip2asn: nil, db_country: nil, db_names: nil) ⇒ Lookup
rubocop:disable Metrics/AbcSize
5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/iptoasn/iptoasn.rb', line 5 def initialize(db_ip2asn: nil, db_country: nil, db_names: nil) # rubocop:disable Metrics/AbcSize if db_ip2asn.nil? || db_country.nil? || db_names.nil? require 'iptoasn/data' db_ip2asn = IpToAsn::Data.ip2asn db_country = IpToAsn::Data.countries db_names = IpToAsn::Data.asnames end @db_ip2asn = File.open(db_ip2asn, 'r') @db_country = File.read(db_country) @db_names = File.open(db_names, 'r') @reserved_ranges = { IPAddr.new('10.0.0.0/8') => 'RFC1918 Private', IPAddr.new('172.16.0.0/12') => 'RFC1918 Private', IPAddr.new('192.168.0.0/16') => 'RFC1918 Private', IPAddr.new('0.0.0.0/8') => 'Current Network', IPAddr.new('127.0.0.0/8') => 'Loopback', IPAddr.new('169.254.0.0/16') => 'Link Local' } @entry_size = IpToAsn::AsEntry.size @db_ip2asn.seek(0, IO::SEEK_END) @db_total_entries = @db_ip2asn.size / @entry_size @db_ip2asn.seek(0) @mutex = Mutex.new end |
Instance Method Details
#as_name(name_offset, name_length) ⇒ Object
37 38 39 40 |
# File 'lib/iptoasn/iptoasn.rb', line 37 def as_name(name_offset, name_length) @db_names.seek(name_offset, IO::SEEK_SET) @db_names.read(name_length) end |
#country(country_index) ⇒ Object
42 43 44 |
# File 'lib/iptoasn/iptoasn.rb', line 42 def country(country_index) @db_country[country_index * 2, 2] end |
#find_range(ranges:, ip_address:) ⇒ Object
87 88 89 90 91 |
# File 'lib/iptoasn/iptoasn.rb', line 87 def find_range(ranges:, ip_address:) ranges.filter_map do |k, v| v if k.include? ip_address end.first end |
#ip_to_int(ip) ⇒ Object
33 34 35 |
# File 'lib/iptoasn/iptoasn.rb', line 33 def ip_to_int(ip) ip.split('.').map(&:to_i).inject(0) { |acc, num| (acc << 8) | num } end |
#lookup(ip) ⇒ Object
46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'lib/iptoasn/iptoasn.rb', line 46 def lookup(ip) reserved_range_name = find_range( ranges: @reserved_ranges, ip_address: ip ) return { as_number: 0, country_code: 'XX', as_name: reserved_range_name } unless reserved_range_name.nil? @mutex.synchronize do search_db(ip) end end |
#search_db(ip) ⇒ Object
rubocop:disable Metrics/AbcSize
59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 |
# File 'lib/iptoasn/iptoasn.rb', line 59 def search_db(ip) # rubocop:disable Metrics/AbcSize ip_int = ip_to_int(ip) left = 0 right = @db_total_entries - 1 while left <= right mid = (left + right) / 2 @db_ip2asn.seek(mid * @entry_size, IO::SEEK_SET) data = @db_ip2asn.read(@entry_size) break if data.nil? || data.size < @entry_size entry = IpToAsn::AsEntry.deserialize(data) if entry.range_start.to_i <= ip_int && ip_int <= entry.range_end.to_i return { as_number: entry.number, as_name: as_name(entry.name_offset, entry.name_length), country_code: country(entry.country) } elsif ip_int < entry.range_start.to_i right = mid - 1 else left = mid + 1 end end end |