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