iptoasn 1.0.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 9443333fd1ae8894b46d9e5373140f8735ef01baf007558bb4c9aefaa13c80a9
4
- data.tar.gz: 7efe3470ae264bfff4af3693414339c7013467c8186ba63cc69a086480c65ec3
3
+ metadata.gz: 35a255d0f44e5d8c30e8b16f43a6827d755efd5d82309cda9097952791acf07b
4
+ data.tar.gz: b9e5b9bf9d8a908a34fee0f1f8ba67831e170c60ebe85e46a2eb60eed65851a3
5
5
  SHA512:
6
- metadata.gz: 90669d169e556629bb2c8fffeaa7d9365d835562eae7581353068c98a1c66ee8acc07e3a93b7a844734a79fe58ff455cba57dcc45238ad2c53360586a6ea627a
7
- data.tar.gz: dada5a7be40ab8fa831ba02e812414c472127b92963a0171a1b3b8ca0cc6844c0005414944bd7ad3c0e9223b2157e9c18d6b8f581b8fbb263e14bb532358a9d8
6
+ metadata.gz: dd0f1ec6eb277b812dcac18db162314481ebd5d9ca49d43ce8ea470152649035478e632267bc3baa96b16df1196930445234d92f178039bca4fd2162a19b23d1
7
+ data.tar.gz: 1e6e339f59892c5c70b33882d40bbe443b452410a185f4bf51e6a9713fad25b0ad2978a07fa26845657ac1d06aaf554309c0046a746f687046c776fcd082508d
@@ -0,0 +1,45 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IpToAsn
4
+ DB_MAIN = 'ip2asn.dat'
5
+ DB_COUNTRIES = 'countries.dat'
6
+ DB_ASNAMES = 'asnames.dat'
7
+ end
8
+
9
+ module IpToAsn
10
+ class AsEntry
11
+ attr_accessor :range_start, :range_end, :number, :country, :name_offset, :name_length
12
+
13
+ def initialize(range_start, range_end, number, country, name_offset, name_length) # rubocop:disable Metrics/ParameterLists
14
+ @range_start = ip_to_int(range_start)
15
+ @range_end = ip_to_int(range_end)
16
+ @number = number
17
+ @country = country
18
+ @name_offset = name_offset
19
+ @name_length = name_length
20
+ end
21
+
22
+ def serialize
23
+ [@range_start, @range_end, @number, @country, @name_offset, @name_length].pack('L L L C L C')
24
+ end
25
+
26
+ def self.deserialize(binary_data)
27
+ range_start, range_end, number, country, name_offset, name_length = binary_data.unpack('L L L C L C')
28
+ new(int_to_ip(range_start), int_to_ip(range_end), number, country, name_offset, name_length)
29
+ end
30
+
31
+ def self.size
32
+ 18 # L + L + L + C + L + C = 18 bytes
33
+ end
34
+
35
+ def self.int_to_ip(int)
36
+ [24, 16, 8, 0].map { |b| (int >> b) & 0xFF }.join('.')
37
+ end
38
+
39
+ private
40
+
41
+ def ip_to_int(ip)
42
+ ip.split('.').map(&:to_i).inject(0) { |acc, num| (acc << 8) | num }
43
+ end
44
+ end
45
+ end
@@ -0,0 +1,90 @@
1
+ # frozen_string_literal: true
2
+
3
+ module IpToAsn
4
+ class Lookup
5
+ def initialize(db_ip2asn: nil, db_country: nil, db_names: nil) # rubocop:disable Metrics/AbcSize
6
+ if db_ip2asn.nil? || db_country.nil? || db_names.nil?
7
+ require 'iptoasn/data'
8
+ db_ip2asn = IpToAsn::Data.ip2asn
9
+ db_country = IpToAsn::Data.countries
10
+ db_names = IpToAsn::Data.asnames
11
+ end
12
+
13
+ @db_ip2asn = File.open(db_ip2asn, 'r')
14
+ @db_country = File.read(db_country)
15
+ @db_names = File.open(db_names, 'r')
16
+
17
+ @reserved_ranges = {
18
+ IPAddr.new('10.0.0.0/8') => 'RFC1918 Private',
19
+ IPAddr.new('172.16.0.0/12') => 'RFC1918 Private',
20
+ IPAddr.new('192.168.0.0/16') => 'RFC1918 Private',
21
+ IPAddr.new('0.0.0.0/8') => 'Current Network',
22
+ IPAddr.new('127.0.0.0/8') => 'Loopback',
23
+ IPAddr.new('169.254.0.0/16') => 'Link Local'
24
+ }
25
+
26
+ @entry_size = IpToAsn::AsEntry.size
27
+ @db_ip2asn.seek(0, IO::SEEK_END)
28
+ @db_total_entries = @db_ip2asn.size / @entry_size
29
+ @db_ip2asn.seek(0)
30
+ end
31
+
32
+ def ip_to_int(ip)
33
+ ip.split('.').map(&:to_i).inject(0) { |acc, num| (acc << 8) | num }
34
+ end
35
+
36
+ def as_name(name_offset, name_length)
37
+ @db_names.seek(name_offset, IO::SEEK_SET)
38
+ @db_names.read(name_length)
39
+ end
40
+
41
+ def country(country_index)
42
+ @db_country[country_index * 2, 2]
43
+ end
44
+
45
+ def lookup(ip)
46
+ reserved_range_name = find_range(
47
+ ranges: @reserved_ranges,
48
+ ip_address: ip
49
+ )
50
+
51
+ return { as_number: 0, country_code: 'XX', as_name: reserved_range_name } unless reserved_range_name.nil?
52
+
53
+ search_db(ip)
54
+ end
55
+
56
+ def search_db(ip) # rubocop:disable Metrics/AbcSize
57
+ ip_int = ip_to_int(ip)
58
+
59
+ left = 0
60
+ right = @db_total_entries - 1
61
+
62
+ while left <= right
63
+ mid = (left + right) / 2
64
+ @db_ip2asn.seek(mid * @entry_size, IO::SEEK_SET)
65
+ data = @db_ip2asn.read(@entry_size)
66
+ break if data.nil? || data.size < @entry_size
67
+
68
+ entry = IpToAsn::AsEntry.deserialize(data)
69
+
70
+ if entry.range_start.to_i <= ip_int && ip_int <= entry.range_end.to_i
71
+ return {
72
+ as_number: entry.number,
73
+ as_name: as_name(entry.name_offset, entry.name_length),
74
+ country_code: country(entry.country)
75
+ }
76
+ elsif ip_int < entry.range_start.to_i
77
+ right = mid - 1
78
+ else
79
+ left = mid + 1
80
+ end
81
+ end
82
+ end
83
+
84
+ def find_range(ranges:, ip_address:)
85
+ ranges.filter_map do |k, v|
86
+ v if k.include? ip_address
87
+ end.first
88
+ end
89
+ end
90
+ end
data/lib/iptoasn.rb CHANGED
@@ -1,3 +1,4 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- require_relative 'main'
3
+ require_relative 'iptoasn/iptoasn'
4
+ require_relative 'iptoasn/asentry'
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: iptoasn
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.0.0
4
+ version: 1.2.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - OMAR
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2025-01-28 00:00:00.000000000 Z
11
+ date: 2025-02-08 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: This gem wraps the IP to ASN dataset. It uses lazy loading so it doesn't
14
14
  load the entire ~25M dataset all at once.
@@ -18,33 +18,9 @@ extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
20
  - README.md
21
- - lib/chunks/chunk_aa.rb
22
- - lib/chunks/chunk_ab.rb
23
- - lib/chunks/chunk_ac.rb
24
- - lib/chunks/chunk_ad.rb
25
- - lib/chunks/chunk_ae.rb
26
- - lib/chunks/chunk_af.rb
27
- - lib/chunks/chunk_ag.rb
28
- - lib/chunks/chunk_ah.rb
29
- - lib/chunks/chunk_ai.rb
30
- - lib/chunks/chunk_aj.rb
31
- - lib/chunks/chunk_ak.rb
32
- - lib/chunks/chunk_al.rb
33
- - lib/chunks/chunk_am.rb
34
- - lib/chunks/chunk_an.rb
35
- - lib/chunks/chunk_ao.rb
36
- - lib/chunks/chunk_ap.rb
37
- - lib/chunks/chunk_aq.rb
38
- - lib/chunks/chunk_ar.rb
39
- - lib/chunks/chunk_as.rb
40
- - lib/chunks/chunk_at.rb
41
- - lib/chunks/chunk_au.rb
42
- - lib/chunks/chunk_av.rb
43
- - lib/chunks/chunk_aw.rb
44
- - lib/chunks/chunk_ax.rb
45
- - lib/index.rb
46
21
  - lib/iptoasn.rb
47
- - lib/main.rb
22
+ - lib/iptoasn/asentry.rb
23
+ - lib/iptoasn/iptoasn.rb
48
24
  homepage: https://github.com/ancat/iptoasn
49
25
  licenses:
50
26
  - MIT