lib/ip2proxy_ruby.rb in ip2proxy_ruby-2.0.0 vs lib/ip2proxy_ruby.rb in ip2proxy_ruby-2.1.0
- old
+ new
@@ -7,11 +7,11 @@
require_relative 'ip2proxy_ruby/ip2proxy_record'
class Ip2proxy
attr_accessor :record_class4, :record_class6, :v4, :file, :db_index, :count, :base_addr, :ipno, :record, :database, :columns, :ip_version, :ipv4databasecount, :ipv4databaseaddr, :ipv4indexbaseaddr, :ipv6databasecount, :ipv6databaseaddr, :ipv6indexbaseaddr, :databaseyear, :databasemonth, :databaseday
- VERSION = '2.0.0'
+ VERSION = '2.1.0'
FIELD_NOT_SUPPORTED = 'NOT SUPPORTED'
INVALID_IP_ADDRESS = 'INVALID IP ADDRESS'
def open(url)
self.file = File.open(File.expand_path url, 'rb')
@@ -49,27 +49,32 @@
return (self.databaseyear).to_s + "." + (self.databasemonth).to_s + "." + (self.databaseday).to_s
end
def get_record(ip)
ipno = IPAddr.new(ip, Socket::AF_UNSPEC)
- self.ip_version = ipno.ipv4? ? 4 : 6
- self.v4 = ipno.ipv4?
- self.count = ipno.ipv4? ? self.ipv4databasecount + 0 : self.ipv6databasecount + 0
- self.base_addr = (ipno.ipv4? ? self.ipv4databaseaddr - 1 : self.ipv6databaseaddr - 1)
-
- ipnum = ipno.to_i + 0
+ self.ip_version, ipnum = validateip(ipno)
+ self.v4 = ip_version == 4 ? true : false
+ self.count = v4 ? self.ipv4databasecount + 0 : self.ipv6databasecount + 0
+ self.base_addr = (v4 ? self.ipv4databaseaddr - 1 : self.ipv6databaseaddr - 1)
col_length = columns * 4
-
if ipv4indexbaseaddr > 0 || ipv6indexbaseaddr > 0
indexpos = 0
case ip_version
when 4
- ipnum1_2 = (ipnum >> 16)
- indexpos = ipv4indexbaseaddr + (ipnum1_2 << 3)
+ indexpos = ipv4indexbaseaddr + ((ipnum >> 16) << 3)
+ realipno = ipnum
+ # if ipnum reach MAX_IPV4_RANGE
+ if realipno == 4294967295
+ ipnum = realipno - 1
+ end
when 6
- ipnum1 = (ipnum / (2**112))
- indexpos = ipv6indexbaseaddr + (ipnum1 << 3)
+ indexpos = ipv6indexbaseaddr + ((ipnum >> 112) << 3)
+ realipno = ipnum
+ # if ipnum reach MAX_IPV6_RANGE
+ if realipno == 340282366920938463463374607431768211455
+ ipnum = realipno - 1
+ end
end
low = read32(indexpos)
high = read32(indexpos + 4)
return self.record = bsearch(low, high, ipnum, self.base_addr, col_length)
else
@@ -275,11 +280,10 @@
domain = (defined?(rec.domain) && rec.domain != '') ? rec.domain : FIELD_NOT_SUPPORTED
usagetype = (defined?(rec.usagetype) && rec.usagetype != '') ? rec.usagetype : FIELD_NOT_SUPPORTED
asn = (defined?(rec.asn) && rec.asn != '') ? rec.asn : FIELD_NOT_SUPPORTED
as = (defined?(rec.as) && rec.as != '') ? rec.as : FIELD_NOT_SUPPORTED
last_seen = (defined?(rec.lastseen) && rec.lastseen != '') ? rec.lastseen : FIELD_NOT_SUPPORTED
-
if self.db_index == 1
isproxy = (rec.country_short == '-') ? 0 : 1
else
isproxy = (rec.proxytype == '-') ? 0 : (rec.proxytype == 'DCH' || rec.proxytype == 'SES') ? 2 : 1
end
@@ -309,11 +313,10 @@
asn = INVALID_IP_ADDRESS
as = INVALID_IP_ADDRESS
last_seen = INVALID_IP_ADDRESS
isproxy = -1
end
-
results = {}
results['is_proxy'] = isproxy
results['proxy_type'] = proxytype
results['country_short'] = country_short
results['country_long'] = country_long
@@ -323,11 +326,10 @@
results['domain'] = domain
results['usagetype'] = usagetype
results['asn'] = asn
results['as'] = as
results['last_seen'] = last_seen
-
return results
end
def bsearch(low, high, ipnum, base_addr, col_length)
while low <= high do
@@ -346,19 +348,51 @@
high = mid - 1
else
low = mid + 1
end
end
- end
+ end
end
def get_from_to(mid, base_addr, col_length)
from_base = ( base_addr + mid * (col_length + (v4 ? 0 : 12)))
file.seek(from_base)
ip_from = v4 ? file.read(4).unpack('V').first : readipv6(file)
file.seek(from_base + col_length + (v4 ? 0 : 12))
ip_to = v4 ? file.read(4).unpack('V').first : readipv6(file)
[ip_from, ip_to]
+ end
+
+ def validateip(ip)
+ if ip.ipv4?
+ ipv = 4
+ ipnum = ip.to_i + 0
+ else
+ ipv = 6
+ ipnum = ip.to_i + 0
+ #reformat ipv4 address in ipv6
+ if ipnum >= 281470681743360 && ipnum <= 281474976710655
+ ipv = 4
+ ipnum = ipnum - 281470681743360
+ end
+ #reformat 6to4 address to ipv4 address 2002:: to 2002:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
+ if ipnum >= 42545680458834377588178886921629466624 && ipnum <= 42550872755692912415807417417958686719
+ ipv = 4
+ #bitshift right 80 bits
+ ipnum = ipnum >> 80
+ #bitwise modulus to get the last 32 bit
+ ipnum = ipnum % 4294967296
+ end
+ #reformat Teredo address to ipv4 address 2001:0000:: to 2001:0000:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:
+ if ipnum >= 42540488161975842760550356425300246528 && ipnum <= 42540488241204005274814694018844196863
+ ipv = 4
+ #bitwise not to invert binary
+ ipnum = ~ipnum
+ #bitwise modulus to get the last 32 bit
+ ipnum = ipnum % 4294967296
+ end
+ end
+ [ipv, ipnum]
end
def read32(indexp)
file.seek(indexp - 1)
return file.read(4).unpack('V').first
\ No newline at end of file