Skip to content

Commit 7f27228

Browse files
committed
Added support for 6to4 and Teredo
1 parent ad65b88 commit 7f27228

File tree

6 files changed

+55
-21
lines changed

6 files changed

+55
-21
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Below are the methods supported in this module.
2222
|---|---|
2323
|open|Open the IP2Proxy BIN data with **File I/O** mode for lookup.|
2424
|close|Close and clean up the file pointer.|
25-
|get_package_version|Get the package version (1 to 4 for PX1 to PX4 respectively).|
25+
|get_package_version|Get the package version (1 to 8 for PX1 to PX8 respectively).|
2626
|get_module_version|Get the module version.|
2727
|get_database_version|Get the database version.|
2828
|is_proxy|Check whether if an IP address was a proxy. Please see [Proxy Type](#proxy-type) for details. Returned value:<ul><li>-1 : errors</li><li>0 : not a proxy</li><li>1 : a proxy</li><li>2 : a data center IP address</li></ul>|
@@ -115,5 +115,5 @@ i2p.close()
115115

116116
## Support
117117

118-
118+
119119
URL: [https://www.ip2location.com](https://www.ip2location.com)

example.rb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
require 'ip2proxy_ruby'
22

33
# open IP2Proxy BIN database for proxy lookup
4-
i2p = Ip2proxy.new.open("./data/IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP-DOMAIN-USAGETYPE-ASN-LASTSEEN.BIN")
4+
i2p = Ip2proxy.new.open("./data/IP2PROXY-LITE-PX1.BIN")
55

66
# get versioning information
77
print 'Module Version: ' + i2p.get_module_version + "\n"

ip2proxy_ruby.gemspec

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22

33
Gem::Specification.new do |s|
44
s.name = "ip2proxy_ruby"
5-
s.version = "2.0.0"
5+
s.version = "2.1.0"
66
s.authors = ["ip2location"]
77
s.email = ["[email protected]"]
88

@@ -34,7 +34,7 @@ Gem::Specification.new do |s|
3434
"spec/assets/IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP.SAMPLE.BIN",
3535
"spec/ip2proxy_ruby_spec.rb",
3636
"spec/spec_helper.rb",
37-
"rb/data/IP2PROXY-IP-PROXYTYPE-COUNTRY-REGION-CITY-ISP.SAMPLE.BIN"
37+
"rb/data/IP2PROXY-LITE-PX1.BIN"
3838
]
3939

4040
if s.respond_to?(:metadata=)

lib/ip2proxy_ruby.rb

Lines changed: 50 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
class Ip2proxy
1010
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
1111

12-
VERSION = '2.0.0'
12+
VERSION = '2.1.0'
1313
FIELD_NOT_SUPPORTED = 'NOT SUPPORTED'
1414
INVALID_IP_ADDRESS = 'INVALID IP ADDRESS'
1515

@@ -51,23 +51,28 @@ def get_database_version()
5151

5252
def get_record(ip)
5353
ipno = IPAddr.new(ip, Socket::AF_UNSPEC)
54-
self.ip_version = ipno.ipv4? ? 4 : 6
55-
self.v4 = ipno.ipv4?
56-
self.count = ipno.ipv4? ? self.ipv4databasecount + 0 : self.ipv6databasecount + 0
57-
self.base_addr = (ipno.ipv4? ? self.ipv4databaseaddr - 1 : self.ipv6databaseaddr - 1)
58-
59-
ipnum = ipno.to_i + 0
54+
self.ip_version, ipnum = validateip(ipno)
55+
self.v4 = ip_version == 4 ? true : false
56+
self.count = v4 ? self.ipv4databasecount + 0 : self.ipv6databasecount + 0
57+
self.base_addr = (v4 ? self.ipv4databaseaddr - 1 : self.ipv6databaseaddr - 1)
6058
col_length = columns * 4
61-
6259
if ipv4indexbaseaddr > 0 || ipv6indexbaseaddr > 0
6360
indexpos = 0
6461
case ip_version
6562
when 4
66-
ipnum1_2 = (ipnum >> 16)
67-
indexpos = ipv4indexbaseaddr + (ipnum1_2 << 3)
63+
indexpos = ipv4indexbaseaddr + ((ipnum >> 16) << 3)
64+
realipno = ipnum
65+
# if ipnum reach MAX_IPV4_RANGE
66+
if realipno == 4294967295
67+
ipnum = realipno - 1
68+
end
6869
when 6
69-
ipnum1 = (ipnum / (2**112))
70-
indexpos = ipv6indexbaseaddr + (ipnum1 << 3)
70+
indexpos = ipv6indexbaseaddr + ((ipnum >> 112) << 3)
71+
realipno = ipnum
72+
# if ipnum reach MAX_IPV6_RANGE
73+
if realipno == 340282366920938463463374607431768211455
74+
ipnum = realipno - 1
75+
end
7176
end
7277
low = read32(indexpos)
7378
high = read32(indexpos + 4)
@@ -277,7 +282,6 @@ def get_all(ip)
277282
asn = (defined?(rec.asn) && rec.asn != '') ? rec.asn : FIELD_NOT_SUPPORTED
278283
as = (defined?(rec.as) && rec.as != '') ? rec.as : FIELD_NOT_SUPPORTED
279284
last_seen = (defined?(rec.lastseen) && rec.lastseen != '') ? rec.lastseen : FIELD_NOT_SUPPORTED
280-
281285
if self.db_index == 1
282286
isproxy = (rec.country_short == '-') ? 0 : 1
283287
else
@@ -311,7 +315,6 @@ def get_all(ip)
311315
last_seen = INVALID_IP_ADDRESS
312316
isproxy = -1
313317
end
314-
315318
results = {}
316319
results['is_proxy'] = isproxy
317320
results['proxy_type'] = proxytype
@@ -325,7 +328,6 @@ def get_all(ip)
325328
results['asn'] = asn
326329
results['as'] = as
327330
results['last_seen'] = last_seen
328-
329331
return results
330332
end
331333

@@ -348,7 +350,7 @@ def bsearch(low, high, ipnum, base_addr, col_length)
348350
low = mid + 1
349351
end
350352
end
351-
end
353+
end
352354
end
353355

354356
def get_from_to(mid, base_addr, col_length)
@@ -360,6 +362,38 @@ def get_from_to(mid, base_addr, col_length)
360362
[ip_from, ip_to]
361363
end
362364

365+
def validateip(ip)
366+
if ip.ipv4?
367+
ipv = 4
368+
ipnum = ip.to_i + 0
369+
else
370+
ipv = 6
371+
ipnum = ip.to_i + 0
372+
#reformat ipv4 address in ipv6
373+
if ipnum >= 281470681743360 && ipnum <= 281474976710655
374+
ipv = 4
375+
ipnum = ipnum - 281470681743360
376+
end
377+
#reformat 6to4 address to ipv4 address 2002:: to 2002:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
378+
if ipnum >= 42545680458834377588178886921629466624 && ipnum <= 42550872755692912415807417417958686719
379+
ipv = 4
380+
#bitshift right 80 bits
381+
ipnum = ipnum >> 80
382+
#bitwise modulus to get the last 32 bit
383+
ipnum = ipnum % 4294967296
384+
end
385+
#reformat Teredo address to ipv4 address 2001:0000:: to 2001:0000:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:
386+
if ipnum >= 42540488161975842760550356425300246528 && ipnum <= 42540488241204005274814694018844196863
387+
ipv = 4
388+
#bitwise not to invert binary
389+
ipnum = ~ipnum
390+
#bitwise modulus to get the last 32 bit
391+
ipnum = ipnum % 4294967296
392+
end
393+
end
394+
[ipv, ipnum]
395+
end
396+
363397
def read32(indexp)
364398
file.seek(indexp - 1)
365399
return file.read(4).unpack('V').first
Binary file not shown.

rb/data/IP2PROXY-LITE-PX1.BIN

86.6 MB
Binary file not shown.

0 commit comments

Comments
 (0)