ip2proxy_ruby 3.3.1 → 3.5.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.
data/lib/ip2proxy_ruby.rb CHANGED
@@ -1,527 +1,546 @@
1
- require 'bindata'
2
- require 'ipaddr'
3
- require 'net/http'
4
- require 'json'
5
- require_relative 'ip2proxy_ruby/ip2proxy_config'
6
- require_relative 'ip2proxy_ruby/i2p_database_config'
7
- require_relative 'ip2proxy_ruby/i2p_string_data'
8
- require_relative 'ip2proxy_ruby/i2p_ip_data'
9
- require_relative 'ip2proxy_ruby/ip2proxy_record'
10
-
11
- class Ip2proxy
12
- 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, :last_err_msg
13
-
14
- VERSION = '3.3.1'
15
- FIELD_NOT_SUPPORTED = 'NOT SUPPORTED'
16
- INVALID_IP_ADDRESS = 'INVALID IP ADDRESS'
17
- INVALID_BIN_DATABASE = 'Incorrect IP2Proxy BIN file format. Please make sure that you are using the latest IP2Proxy BIN file.'
18
-
19
- def open(url)
20
- if url == ''
21
- self.last_err_msg = 'Ip2proxy.new.open() requires a database path name.'
22
- abort('Ip2proxy.new.open() requires a database path name.')
23
- end
24
-
25
- begin
26
- self.file = File.open(File.expand_path url, 'rb')
27
- rescue
28
- self.last_err_msg = 'Ip2proxy.new.open() error in opening ' + url +'.'
29
- abort('Ip2proxy.new.open() error in opening ' + url + '. No such file in the /your_ip2proxy_ruby_library_path/rb/ folder.')
30
- else
31
- end
32
- i2p = Ip2proxyConfig.read(file)
33
- if i2p.productcode == 2
34
- else
35
- if i2p.databaseyear <= 20 && i2p.productcode == 0
36
- else
37
- self.file.close
38
- self.last_err_msg = INVALID_BIN_DATABASE
39
- abort(INVALID_BIN_DATABASE)
40
- end
41
- end
42
- self.db_index = i2p.databasetype
43
- self.columns = i2p.databasecolumn + 0
44
- self.databaseyear = 2000 + i2p.databaseyear
45
- self.databasemonth = i2p.databasemonth
46
- self.databaseday = i2p.databaseday
47
- self.database = I2pDbConfig.setup_database(self.db_index)
48
- self.ipv4databasecount = i2p.ipv4databasecount
49
- self.ipv4databaseaddr = i2p.ipv4databaseaddr
50
- self.ipv6databasecount = i2p.ipv6databasecount
51
- self.ipv6databaseaddr = i2p.ipv6databaseaddr
52
- self.ipv4indexbaseaddr = i2p.ipv4indexbaseaddr
53
- self.ipv6indexbaseaddr = i2p.ipv6indexbaseaddr
54
- self.record_class4 = (Ip2ProxyRecord.init database, 4)
55
- self.record_class6 = (Ip2ProxyRecord.init database, 6)
56
- self
57
- end
58
-
59
- def close()
60
- self.file.close
61
- end
62
-
63
- def get_last_error_message()
64
- return self.last_err_msg
65
- end
66
-
67
- def get_module_version()
68
- return VERSION
69
- end
70
-
71
- def get_package_version()
72
- return (self.db_index).to_s
73
- end
74
-
75
- def get_database_version()
76
- return (self.databaseyear).to_s + "." + (self.databasemonth).to_s + "." + (self.databaseday).to_s
77
- end
78
-
79
- def get_record(ip)
80
- ipno = IPAddr.new(ip, Socket::AF_UNSPEC)
81
- self.ip_version, ipnum = validateip(ipno)
82
- self.v4 = ip_version == 4 ? true : false
83
- self.count = v4 ? self.ipv4databasecount + 0 : self.ipv6databasecount + 0
84
- self.base_addr = (v4 ? self.ipv4databaseaddr - 1 : self.ipv6databaseaddr - 1)
85
- col_length = columns * 4
86
- if ipv4indexbaseaddr > 0 || ipv6indexbaseaddr > 0
87
- indexpos = 0
88
- case ip_version
89
- when 4
90
- indexpos = ipv4indexbaseaddr + ((ipnum >> 16) << 3)
91
- realipno = ipnum
92
- # if ipnum reach MAX_IPV4_RANGE
93
- if realipno == 4294967295
94
- ipnum = realipno - 1
95
- end
96
- when 6
97
- indexpos = ipv6indexbaseaddr + ((ipnum >> 112) << 3)
98
- realipno = ipnum
99
- # if ipnum reach MAX_IPV6_RANGE
100
- if realipno == 340282366920938463463374607431768211455
101
- ipnum = realipno - 1
102
- end
103
- end
104
- low, high = read32x2(indexpos)
105
- return self.record = bsearch(low, high, ipnum, self.base_addr, col_length)
106
- else
107
- return self.record = bsearch(0, self.count, ipnum, self.base_addr, col_length)
108
- end
109
- end
110
-
111
- def get_country_short(ip)
112
- valid = !(IPAddr.new(ip) rescue nil).nil?
113
- if valid
114
- rec = get_record(ip)
115
- if !(rec.nil?)
116
- country_short = (defined?(rec.country_short) && rec.country_short != '') ? rec.country_short : FIELD_NOT_SUPPORTED
117
- else
118
- country_short = INVALID_IP_ADDRESS
119
- end
120
- else
121
- country_short = INVALID_IP_ADDRESS
122
- end
123
- return country_short
124
- end
125
-
126
- def get_country_long(ip)
127
- valid = !(IPAddr.new(ip) rescue nil).nil?
128
- if valid
129
- rec = get_record(ip)
130
- if !(rec.nil?)
131
- country_long = (defined?(rec.country_long) && rec.country_long != '') ? rec.country_long : FIELD_NOT_SUPPORTED
132
- else
133
- country_long = INVALID_IP_ADDRESS
134
- end
135
- else
136
- country_long = INVALID_IP_ADDRESS
137
- end
138
- return country_long
139
- end
140
-
141
- def get_region(ip)
142
- valid = !(IPAddr.new(ip) rescue nil).nil?
143
- if valid
144
- rec = get_record(ip)
145
- if !(rec.nil?)
146
- region = (defined?(rec.region) && rec.region != '') ? rec.region : FIELD_NOT_SUPPORTED
147
- else
148
- region = INVALID_IP_ADDRESS
149
- end
150
- else
151
- region = INVALID_IP_ADDRESS
152
- end
153
- return region
154
- end
155
-
156
- def get_city(ip)
157
- valid = !(IPAddr.new(ip) rescue nil).nil?
158
- if valid
159
- rec = get_record(ip)
160
- if !(rec.nil?)
161
- city = (defined?(rec.city) && rec.city != '') ? rec.city : FIELD_NOT_SUPPORTED
162
- else
163
- city = INVALID_IP_ADDRESS
164
- end
165
- else
166
- city = INVALID_IP_ADDRESS
167
- end
168
- return city
169
- end
170
-
171
- def get_isp(ip)
172
- valid = !(IPAddr.new(ip) rescue nil).nil?
173
- if valid
174
- rec = get_record(ip)
175
- if !(rec.nil?)
176
- isp = (defined?(rec.isp) && rec.isp != '') ? rec.isp : FIELD_NOT_SUPPORTED
177
- else
178
- isp = INVALID_IP_ADDRESS
179
- end
180
- else
181
- isp = INVALID_IP_ADDRESS
182
- end
183
- return isp
184
- end
185
-
186
- def get_proxytype(ip)
187
- valid = !(IPAddr.new(ip) rescue nil).nil?
188
- if valid
189
- rec = get_record(ip)
190
- if !(rec.nil?)
191
- proxytype = (defined?(rec.proxytype) && rec.proxytype != '') ? rec.proxytype : FIELD_NOT_SUPPORTED
192
- else
193
- proxytype = INVALID_IP_ADDRESS
194
- end
195
- else
196
- proxytype = INVALID_IP_ADDRESS
197
- end
198
- return proxytype
199
- end
200
-
201
- def get_domain(ip)
202
- valid = !(IPAddr.new(ip) rescue nil).nil?
203
- if valid
204
- rec = get_record(ip)
205
- if !(rec.nil?)
206
- domain = (defined?(rec.domain) && rec.domain != '') ? rec.domain : FIELD_NOT_SUPPORTED
207
- else
208
- domain = INVALID_IP_ADDRESS
209
- end
210
- else
211
- domain = INVALID_IP_ADDRESS
212
- end
213
- return domain
214
- end
215
-
216
- def get_usagetype(ip)
217
- valid = !(IPAddr.new(ip) rescue nil).nil?
218
- if valid
219
- rec = get_record(ip)
220
- if !(rec.nil?)
221
- usagetype = (defined?(rec.usagetype) && rec.usagetype != '') ? rec.usagetype : FIELD_NOT_SUPPORTED
222
- else
223
- usagetype = INVALID_IP_ADDRESS
224
- end
225
- else
226
- usagetype = INVALID_IP_ADDRESS
227
- end
228
- return usagetype
229
- end
230
-
231
- def get_asn(ip)
232
- valid = !(IPAddr.new(ip) rescue nil).nil?
233
- if valid
234
- rec = get_record(ip)
235
- if !(rec.nil?)
236
- asn = (defined?(rec.asn) && rec.asn != '') ? rec.asn : FIELD_NOT_SUPPORTED
237
- else
238
- asn = INVALID_IP_ADDRESS
239
- end
240
- else
241
- asn = INVALID_IP_ADDRESS
242
- end
243
- return asn
244
- end
245
-
246
- def get_as(ip)
247
- valid = !(IPAddr.new(ip) rescue nil).nil?
248
- if valid
249
- rec = get_record(ip)
250
- if !(rec.nil?)
251
- as = (defined?(rec.as) && rec.as != '') ? rec.as : FIELD_NOT_SUPPORTED
252
- else
253
- as = INVALID_IP_ADDRESS
254
- end
255
- else
256
- as = INVALID_IP_ADDRESS
257
- end
258
- return as
259
- end
260
-
261
- def get_last_seen(ip)
262
- valid = !(IPAddr.new(ip) rescue nil).nil?
263
- if valid
264
- rec = get_record(ip)
265
- if !(rec.nil?)
266
- last_seen = (defined?(rec.lastseen) && rec.lastseen != '') ? rec.lastseen : FIELD_NOT_SUPPORTED
267
- else
268
- last_seen = INVALID_IP_ADDRESS
269
- end
270
- else
271
- last_seen = INVALID_IP_ADDRESS
272
- end
273
- return last_seen
274
- end
275
-
276
- def get_threat(ip)
277
- valid = !(IPAddr.new(ip) rescue nil).nil?
278
- if valid
279
- rec = get_record(ip)
280
- if !(rec.nil?)
281
- threat = (defined?(rec.threat) && rec.threat != '') ? rec.threat : FIELD_NOT_SUPPORTED
282
- else
283
- threat = INVALID_IP_ADDRESS
284
- end
285
- else
286
- threat = INVALID_IP_ADDRESS
287
- end
288
- return threat
289
- end
290
-
291
- def is_proxy(ip)
292
- valid = !(IPAddr.new(ip) rescue nil).nil?
293
- if valid
294
- rec = get_record(ip)
295
- if !(rec.nil?)
296
- if self.db_index == 1
297
- isproxy = (rec.country_short == '-') ? 0 : 1
298
- else
299
- isproxy = (rec.proxytype == '-') ? 0 : (rec.proxytype == 'DCH' || rec.proxytype == 'SES') ? 2 : 1
300
- end
301
- else
302
- isproxy = -1
303
- end
304
- else
305
- isproxy = -1
306
- end
307
- return isproxy
308
- end
309
-
310
- def get_provider(ip)
311
- valid = !(IPAddr.new(ip) rescue nil).nil?
312
- if valid
313
- rec = get_record(ip)
314
- if !(rec.nil?)
315
- provider = (defined?(rec.provider) && rec.provider != '') ? rec.provider : FIELD_NOT_SUPPORTED
316
- else
317
- provider = INVALID_IP_ADDRESS
318
- end
319
- else
320
- provider = INVALID_IP_ADDRESS
321
- end
322
- return provider
323
- end
324
-
325
- def get_all(ip)
326
- valid = !(IPAddr.new(ip) rescue nil).nil?
327
- if valid
328
- rec = get_record(ip)
329
- if !(rec.nil?)
330
- country_short = (defined?(rec.country_short) && rec.country_short != '') ? rec.country_short : FIELD_NOT_SUPPORTED
331
- country_long = (defined?(rec.country_long) && rec.country_long != '') ? rec.country_long : FIELD_NOT_SUPPORTED
332
- region = (defined?(rec.region) && rec.region != '') ? rec.region : FIELD_NOT_SUPPORTED
333
- city = (defined?(rec.city) && rec.city != '') ? rec.city : FIELD_NOT_SUPPORTED
334
- isp = (defined?(rec.isp) && rec.isp != '') ? rec.isp : FIELD_NOT_SUPPORTED
335
- proxytype = (defined?(rec.proxytype) && rec.proxytype != '') ? rec.proxytype : FIELD_NOT_SUPPORTED
336
- domain = (defined?(rec.domain) && rec.domain != '') ? rec.domain : FIELD_NOT_SUPPORTED
337
- usagetype = (defined?(rec.usagetype) && rec.usagetype != '') ? rec.usagetype : FIELD_NOT_SUPPORTED
338
- asn = (defined?(rec.asn) && rec.asn != '') ? rec.asn : FIELD_NOT_SUPPORTED
339
- as = (defined?(rec.as) && rec.as != '') ? rec.as : FIELD_NOT_SUPPORTED
340
- last_seen = (defined?(rec.lastseen) && rec.lastseen != '') ? rec.lastseen : FIELD_NOT_SUPPORTED
341
- threat = (defined?(rec.threat) && rec.threat != '') ? rec.threat : FIELD_NOT_SUPPORTED
342
- provider = (defined?(rec.provider) && rec.provider != '') ? rec.provider : FIELD_NOT_SUPPORTED
343
- if self.db_index == 1
344
- isproxy = (rec.country_short == '-') ? 0 : 1
345
- else
346
- isproxy = (rec.proxytype == '-') ? 0 : (rec.proxytype == 'DCH' || rec.proxytype == 'SES') ? 2 : 1
347
- end
348
- else
349
- country_short = INVALID_IP_ADDRESS
350
- country_long = INVALID_IP_ADDRESS
351
- region = INVALID_IP_ADDRESS
352
- city = INVALID_IP_ADDRESS
353
- isp = INVALID_IP_ADDRESS
354
- proxytype = INVALID_IP_ADDRESS
355
- domain = INVALID_IP_ADDRESS
356
- usagetype = INVALID_IP_ADDRESS
357
- asn = INVALID_IP_ADDRESS
358
- as = INVALID_IP_ADDRESS
359
- last_seen = INVALID_IP_ADDRESS
360
- threat = INVALID_IP_ADDRESS
361
- provider = INVALID_IP_ADDRESS
362
- isproxy = -1
363
- end
364
- else
365
- country_short = INVALID_IP_ADDRESS
366
- country_long = INVALID_IP_ADDRESS
367
- region = INVALID_IP_ADDRESS
368
- city = INVALID_IP_ADDRESS
369
- isp = INVALID_IP_ADDRESS
370
- proxytype = INVALID_IP_ADDRESS
371
- domain = INVALID_IP_ADDRESS
372
- usagetype = INVALID_IP_ADDRESS
373
- asn = INVALID_IP_ADDRESS
374
- as = INVALID_IP_ADDRESS
375
- last_seen = INVALID_IP_ADDRESS
376
- threat = INVALID_IP_ADDRESS
377
- provider = INVALID_IP_ADDRESS
378
- isproxy = -1
379
- end
380
- results = {}
381
- results['is_proxy'] = isproxy
382
- results['proxy_type'] = proxytype
383
- results['country_short'] = country_short
384
- results['country_long'] = country_long
385
- results['region'] = region
386
- results['city'] = city
387
- results['isp'] = isp
388
- results['domain'] = domain
389
- results['usagetype'] = usagetype
390
- results['asn'] = asn
391
- results['as'] = as
392
- results['last_seen'] = last_seen
393
- results['threat'] = threat
394
- results['provider'] = provider
395
- return results
396
- end
397
-
398
- def bsearch(low, high, ipnum, base_addr, col_length)
399
- while low <= high do
400
- mid = (low + high) >> 1
401
- ip_from, ip_to = get_from_to(mid, base_addr, col_length)
402
- if ipnum >= ip_from && ipnum < ip_to
403
- from_base = ( base_addr + mid * (col_length + (self.v4 ? 0 : 12)))
404
- file.seek(from_base)
405
- if v4
406
- return self.record_class4.read(file)
407
- else
408
- return self.record_class6.read(file)
409
- end
410
- else
411
- if ipnum < ip_from
412
- high = mid - 1
413
- else
414
- low = mid + 1
415
- end
416
- end
417
- end
418
- end
419
-
420
- def get_from_to(mid, base_addr, col_length)
421
- from_base = (base_addr + mid * (col_length + (v4 ? 0 : 12)))
422
- data_length = col_length + (v4 ? 4 : (12 + 16))
423
- file.seek(from_base)
424
- data_read = file.read(data_length)
425
- ip_from = v4 ? data_read[0..3].unpack('V').first : readipv6(data_read[0..15].unpack('V*'))
426
- ip_to = v4 ? data_read[(data_length - 4)..(data_length - 1)].unpack('V').first : readipv6(data_read[(data_length - 16)..(data_length - 1)].unpack('V*'))
427
- [ip_from, ip_to]
428
- end
429
-
430
- def validateip(ip)
431
- if ip.ipv4?
432
- ipv = 4
433
- ipnum = ip.to_i + 0
434
- else
435
- ipv = 6
436
- ipnum = ip.to_i + 0
437
- #reformat ipv4 address in ipv6
438
- if ipnum >= 281470681743360 && ipnum <= 281474976710655
439
- ipv = 4
440
- ipnum = ipnum - 281470681743360
441
- end
442
- #reformat 6to4 address to ipv4 address 2002:: to 2002:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
443
- if ipnum >= 42545680458834377588178886921629466624 && ipnum <= 42550872755692912415807417417958686719
444
- ipv = 4
445
- #bitshift right 80 bits
446
- ipnum = ipnum >> 80
447
- #bitwise modulus to get the last 32 bit
448
- ipnum = ipnum % 4294967296
449
- end
450
- #reformat Teredo address to ipv4 address 2001:0000:: to 2001:0000:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:
451
- if ipnum >= 42540488161975842760550356425300246528 && ipnum <= 42540488241204005274814694018844196863
452
- ipv = 4
453
- #bitwise not to invert binary
454
- ipnum = ~ipnum
455
- #bitwise modulus to get the last 32 bit
456
- ipnum = ipnum % 4294967296
457
- end
458
- end
459
- [ipv, ipnum]
460
- end
461
-
462
- def read32x2(indexp)
463
- file.seek(indexp - 1)
464
- data_read = file.read(8)
465
- data1 = data_read[0..3].unpack('V').first
466
- data2 = data_read[4..7].unpack('V').first
467
- return [data1, data2]
468
- end
469
-
470
- def readipv6(parts)
471
- return parts[0] + parts[1] * 4294967296 + parts[2] * 4294967296**2 + parts[3] * 4294967296**3
472
- end
473
-
474
- private :get_record, :bsearch, :get_from_to, :read32x2, :readipv6
475
-
476
- end
477
-
478
- class Ip2proxyWebService
479
- attr_accessor :ws_api_key, :ws_package, :ws_use_ssl
480
-
481
- def initialize(api_key, package, use_ssl)
482
- if !api_key.match(/^[0-9A-Z]{10}$/) && api_key != 'demo'
483
- raise Exception.new "Please provide a valid IP2Proxy web service API key."
484
- end
485
- if !package.match(/^PX[0-9]+$/)
486
- package = 'PX1'
487
- end
488
- if use_ssl == ''
489
- use_ssl = true
490
- end
491
- self.ws_api_key = api_key
492
- self.ws_package = package
493
- self.ws_use_ssl = use_ssl
494
- end
495
-
496
- def lookup(ip)
497
- if self.ws_use_ssl
498
- response = Net::HTTP.get(URI("https://api.ip2proxy.com/?key=" + self.ws_api_key + "&ip=" + ip + "&package=" + self.ws_package + "&format=json"))
499
- else
500
- response = Net::HTTP.get(URI("http://api.ip2proxy.com/?key=" + self.ws_api_key + "&ip=" + ip + "&package=" + self.ws_package + "&format=json"))
501
- end
502
- parsed_response = JSON.parse(response)
503
- if parsed_response.nil?
504
- return false
505
- end
506
- if parsed_response["response"] != "OK"
507
- raise Exception.new "Error: " + parsed_response["response"]
508
- end
509
- return parsed_response
510
- end
511
-
512
- def get_credit()
513
- if self.ws_use_ssl
514
- response = Net::HTTP.get(URI("https://api.ip2proxy.com/?key=" + self.ws_api_key + "&check=true"))
515
- else
516
- response = Net::HTTP.get(URI("http://api.ip2proxy.com/?key=" + self.ws_api_key + "&check=true"))
517
- end
518
- parsed_response = JSON.parse(response)
519
- if parsed_response.nil?
520
- return 0
521
- end
522
- if parsed_response["response"].nil?
523
- return 0
524
- end
525
- return parsed_response["response"]
526
- end
1
+ require 'bindata'
2
+ require 'ipaddr'
3
+ require 'net/http'
4
+ require 'json'
5
+ require_relative 'ip2proxy_ruby/ip2proxy_config'
6
+ require_relative 'ip2proxy_ruby/i2p_database_config'
7
+ require_relative 'ip2proxy_ruby/i2p_string_data'
8
+ require_relative 'ip2proxy_ruby/i2p_ip_data'
9
+ require_relative 'ip2proxy_ruby/ip2proxy_record'
10
+
11
+ class Ip2proxy
12
+ 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, :last_err_msg
13
+
14
+ VERSION = '3.5.0'
15
+ FIELD_NOT_SUPPORTED = 'NOT SUPPORTED'
16
+ INVALID_IP_ADDRESS = 'INVALID IP ADDRESS'
17
+ INVALID_BIN_DATABASE = 'Incorrect IP2Proxy BIN file format. Please make sure that you are using the latest IP2Proxy BIN file.'
18
+
19
+ def open(url)
20
+ if url == ''
21
+ self.last_err_msg = 'Ip2proxy.new.open() requires a database path name.'
22
+ abort('Ip2proxy.new.open() requires a database path name.')
23
+ end
24
+
25
+ begin
26
+ self.file = File.open(File.expand_path url, 'rb')
27
+ rescue
28
+ self.last_err_msg = 'Ip2proxy.new.open() error in opening ' + url +'.'
29
+ abort('Ip2proxy.new.open() error in opening ' + url + '. No such file in the /your_ip2proxy_ruby_library_path/rb/ folder.')
30
+ else
31
+ end
32
+ i2p = Ip2proxyConfig.read(file)
33
+ if i2p.productcode == 2
34
+ else
35
+ if i2p.databaseyear <= 20 && i2p.productcode == 0
36
+ else
37
+ self.file.close
38
+ self.last_err_msg = INVALID_BIN_DATABASE
39
+ abort(INVALID_BIN_DATABASE)
40
+ end
41
+ end
42
+ self.db_index = i2p.databasetype
43
+ self.columns = i2p.databasecolumn + 0
44
+ self.databaseyear = 2000 + i2p.databaseyear
45
+ self.databasemonth = i2p.databasemonth
46
+ self.databaseday = i2p.databaseday
47
+ self.database = I2pDbConfig.setup_database(self.db_index)
48
+ self.ipv4databasecount = i2p.ipv4databasecount
49
+ self.ipv4databaseaddr = i2p.ipv4databaseaddr
50
+ self.ipv6databasecount = i2p.ipv6databasecount
51
+ self.ipv6databaseaddr = i2p.ipv6databaseaddr
52
+ self.ipv4indexbaseaddr = i2p.ipv4indexbaseaddr
53
+ self.ipv6indexbaseaddr = i2p.ipv6indexbaseaddr
54
+ self.record_class4 = (Ip2ProxyRecord.init database, 4)
55
+ self.record_class6 = (Ip2ProxyRecord.init database, 6)
56
+ self
57
+ end
58
+
59
+ def close()
60
+ self.file.close
61
+ end
62
+
63
+ def get_last_error_message()
64
+ return self.last_err_msg
65
+ end
66
+
67
+ def get_module_version()
68
+ return VERSION
69
+ end
70
+
71
+ def get_package_version()
72
+ return (self.db_index).to_s
73
+ end
74
+
75
+ def get_database_version()
76
+ return (self.databaseyear).to_s + "." + (self.databasemonth).to_s + "." + (self.databaseday).to_s
77
+ end
78
+
79
+ def get_record(ip)
80
+ ipno = IPAddr.new(ip, Socket::AF_UNSPEC)
81
+ self.ip_version, ipnum = validateip(ipno)
82
+ self.v4 = ip_version == 4 ? true : false
83
+ self.count = v4 ? self.ipv4databasecount + 0 : self.ipv6databasecount + 0
84
+ self.base_addr = (v4 ? self.ipv4databaseaddr - 1 : self.ipv6databaseaddr - 1)
85
+ col_length = columns * 4
86
+ if ipv4indexbaseaddr > 0 || ipv6indexbaseaddr > 0
87
+ indexpos = 0
88
+ case ip_version
89
+ when 4
90
+ indexpos = ipv4indexbaseaddr + ((ipnum >> 16) << 3)
91
+ realipno = ipnum
92
+ # if ipnum reach MAX_IPV4_RANGE
93
+ if realipno == 4294967295
94
+ ipnum = realipno - 1
95
+ end
96
+ when 6
97
+ indexpos = ipv6indexbaseaddr + ((ipnum >> 112) << 3)
98
+ realipno = ipnum
99
+ # if ipnum reach MAX_IPV6_RANGE
100
+ if realipno == 340282366920938463463374607431768211455
101
+ ipnum = realipno - 1
102
+ end
103
+ end
104
+ low, high = read32x2(indexpos)
105
+ return self.record = bsearch(low, high, ipnum, self.base_addr, col_length)
106
+ else
107
+ return self.record = bsearch(0, self.count, ipnum, self.base_addr, col_length)
108
+ end
109
+ end
110
+
111
+ def get_country_short(ip)
112
+ valid = !(IPAddr.new(ip) rescue nil).nil?
113
+ if valid
114
+ rec = get_record(ip)
115
+ if !(rec.nil?)
116
+ country_short = (defined?(rec.country_short) && rec.country_short != '') ? rec.country_short : FIELD_NOT_SUPPORTED
117
+ else
118
+ country_short = INVALID_IP_ADDRESS
119
+ end
120
+ else
121
+ country_short = INVALID_IP_ADDRESS
122
+ end
123
+ return country_short
124
+ end
125
+
126
+ def get_country_long(ip)
127
+ valid = !(IPAddr.new(ip) rescue nil).nil?
128
+ if valid
129
+ rec = get_record(ip)
130
+ if !(rec.nil?)
131
+ country_long = (defined?(rec.country_long) && rec.country_long != '') ? rec.country_long : FIELD_NOT_SUPPORTED
132
+ else
133
+ country_long = INVALID_IP_ADDRESS
134
+ end
135
+ else
136
+ country_long = INVALID_IP_ADDRESS
137
+ end
138
+ return country_long
139
+ end
140
+
141
+ def get_region(ip)
142
+ valid = !(IPAddr.new(ip) rescue nil).nil?
143
+ if valid
144
+ rec = get_record(ip)
145
+ if !(rec.nil?)
146
+ region = (defined?(rec.region) && rec.region != '') ? rec.region : FIELD_NOT_SUPPORTED
147
+ else
148
+ region = INVALID_IP_ADDRESS
149
+ end
150
+ else
151
+ region = INVALID_IP_ADDRESS
152
+ end
153
+ return region
154
+ end
155
+
156
+ def get_city(ip)
157
+ valid = !(IPAddr.new(ip) rescue nil).nil?
158
+ if valid
159
+ rec = get_record(ip)
160
+ if !(rec.nil?)
161
+ city = (defined?(rec.city) && rec.city != '') ? rec.city : FIELD_NOT_SUPPORTED
162
+ else
163
+ city = INVALID_IP_ADDRESS
164
+ end
165
+ else
166
+ city = INVALID_IP_ADDRESS
167
+ end
168
+ return city
169
+ end
170
+
171
+ def get_isp(ip)
172
+ valid = !(IPAddr.new(ip) rescue nil).nil?
173
+ if valid
174
+ rec = get_record(ip)
175
+ if !(rec.nil?)
176
+ isp = (defined?(rec.isp) && rec.isp != '') ? rec.isp : FIELD_NOT_SUPPORTED
177
+ else
178
+ isp = INVALID_IP_ADDRESS
179
+ end
180
+ else
181
+ isp = INVALID_IP_ADDRESS
182
+ end
183
+ return isp
184
+ end
185
+
186
+ def get_proxytype(ip)
187
+ valid = !(IPAddr.new(ip) rescue nil).nil?
188
+ if valid
189
+ rec = get_record(ip)
190
+ if !(rec.nil?)
191
+ proxytype = (defined?(rec.proxytype) && rec.proxytype != '') ? rec.proxytype : FIELD_NOT_SUPPORTED
192
+ else
193
+ proxytype = INVALID_IP_ADDRESS
194
+ end
195
+ else
196
+ proxytype = INVALID_IP_ADDRESS
197
+ end
198
+ return proxytype
199
+ end
200
+
201
+ def get_domain(ip)
202
+ valid = !(IPAddr.new(ip) rescue nil).nil?
203
+ if valid
204
+ rec = get_record(ip)
205
+ if !(rec.nil?)
206
+ domain = (defined?(rec.domain) && rec.domain != '') ? rec.domain : FIELD_NOT_SUPPORTED
207
+ else
208
+ domain = INVALID_IP_ADDRESS
209
+ end
210
+ else
211
+ domain = INVALID_IP_ADDRESS
212
+ end
213
+ return domain
214
+ end
215
+
216
+ def get_usagetype(ip)
217
+ valid = !(IPAddr.new(ip) rescue nil).nil?
218
+ if valid
219
+ rec = get_record(ip)
220
+ if !(rec.nil?)
221
+ usagetype = (defined?(rec.usagetype) && rec.usagetype != '') ? rec.usagetype : FIELD_NOT_SUPPORTED
222
+ else
223
+ usagetype = INVALID_IP_ADDRESS
224
+ end
225
+ else
226
+ usagetype = INVALID_IP_ADDRESS
227
+ end
228
+ return usagetype
229
+ end
230
+
231
+ def get_asn(ip)
232
+ valid = !(IPAddr.new(ip) rescue nil).nil?
233
+ if valid
234
+ rec = get_record(ip)
235
+ if !(rec.nil?)
236
+ asn = (defined?(rec.asn) && rec.asn != '') ? rec.asn : FIELD_NOT_SUPPORTED
237
+ else
238
+ asn = INVALID_IP_ADDRESS
239
+ end
240
+ else
241
+ asn = INVALID_IP_ADDRESS
242
+ end
243
+ return asn
244
+ end
245
+
246
+ def get_as(ip)
247
+ valid = !(IPAddr.new(ip) rescue nil).nil?
248
+ if valid
249
+ rec = get_record(ip)
250
+ if !(rec.nil?)
251
+ as = (defined?(rec.as) && rec.as != '') ? rec.as : FIELD_NOT_SUPPORTED
252
+ else
253
+ as = INVALID_IP_ADDRESS
254
+ end
255
+ else
256
+ as = INVALID_IP_ADDRESS
257
+ end
258
+ return as
259
+ end
260
+
261
+ def get_last_seen(ip)
262
+ valid = !(IPAddr.new(ip) rescue nil).nil?
263
+ if valid
264
+ rec = get_record(ip)
265
+ if !(rec.nil?)
266
+ last_seen = (defined?(rec.lastseen) && rec.lastseen != '') ? rec.lastseen : FIELD_NOT_SUPPORTED
267
+ else
268
+ last_seen = INVALID_IP_ADDRESS
269
+ end
270
+ else
271
+ last_seen = INVALID_IP_ADDRESS
272
+ end
273
+ return last_seen
274
+ end
275
+
276
+ def get_threat(ip)
277
+ valid = !(IPAddr.new(ip) rescue nil).nil?
278
+ if valid
279
+ rec = get_record(ip)
280
+ if !(rec.nil?)
281
+ threat = (defined?(rec.threat) && rec.threat != '') ? rec.threat : FIELD_NOT_SUPPORTED
282
+ else
283
+ threat = INVALID_IP_ADDRESS
284
+ end
285
+ else
286
+ threat = INVALID_IP_ADDRESS
287
+ end
288
+ return threat
289
+ end
290
+
291
+ def is_proxy(ip)
292
+ valid = !(IPAddr.new(ip) rescue nil).nil?
293
+ if valid
294
+ rec = get_record(ip)
295
+ if !(rec.nil?)
296
+ if self.db_index == 1
297
+ isproxy = (rec.country_short == '-') ? 0 : 1
298
+ else
299
+ isproxy = (rec.proxytype == '-') ? 0 : (rec.proxytype == 'DCH' || rec.proxytype == 'SES' || rec.proxytype == 'AIC') ? 2 : 1
300
+ end
301
+ else
302
+ isproxy = -1
303
+ end
304
+ else
305
+ isproxy = -1
306
+ end
307
+ return isproxy
308
+ end
309
+
310
+ def get_provider(ip)
311
+ valid = !(IPAddr.new(ip) rescue nil).nil?
312
+ if valid
313
+ rec = get_record(ip)
314
+ if !(rec.nil?)
315
+ provider = (defined?(rec.provider) && rec.provider != '') ? rec.provider : FIELD_NOT_SUPPORTED
316
+ else
317
+ provider = INVALID_IP_ADDRESS
318
+ end
319
+ else
320
+ provider = INVALID_IP_ADDRESS
321
+ end
322
+ return provider
323
+ end
324
+
325
+ def get_fraud_score(ip)
326
+ valid = !(IPAddr.new(ip) rescue nil).nil?
327
+ if valid
328
+ rec = get_record(ip)
329
+ if !(rec.nil?)
330
+ fraud_score = (defined?(rec.fraud_score) && rec.fraud_score != '') ? rec.fraud_score : FIELD_NOT_SUPPORTED
331
+ else
332
+ fraud_score = INVALID_IP_ADDRESS
333
+ end
334
+ else
335
+ fraud_score = INVALID_IP_ADDRESS
336
+ end
337
+ return fraud_score
338
+ end
339
+
340
+ def get_all(ip)
341
+ valid = !(IPAddr.new(ip) rescue nil).nil?
342
+ if valid
343
+ rec = get_record(ip)
344
+ if !(rec.nil?)
345
+ country_short = (defined?(rec.country_short) && rec.country_short != '') ? rec.country_short : FIELD_NOT_SUPPORTED
346
+ country_long = (defined?(rec.country_long) && rec.country_long != '') ? rec.country_long : FIELD_NOT_SUPPORTED
347
+ region = (defined?(rec.region) && rec.region != '') ? rec.region : FIELD_NOT_SUPPORTED
348
+ city = (defined?(rec.city) && rec.city != '') ? rec.city : FIELD_NOT_SUPPORTED
349
+ isp = (defined?(rec.isp) && rec.isp != '') ? rec.isp : FIELD_NOT_SUPPORTED
350
+ proxytype = (defined?(rec.proxytype) && rec.proxytype != '') ? rec.proxytype : FIELD_NOT_SUPPORTED
351
+ domain = (defined?(rec.domain) && rec.domain != '') ? rec.domain : FIELD_NOT_SUPPORTED
352
+ usagetype = (defined?(rec.usagetype) && rec.usagetype != '') ? rec.usagetype : FIELD_NOT_SUPPORTED
353
+ asn = (defined?(rec.asn) && rec.asn != '') ? rec.asn : FIELD_NOT_SUPPORTED
354
+ as = (defined?(rec.as) && rec.as != '') ? rec.as : FIELD_NOT_SUPPORTED
355
+ last_seen = (defined?(rec.lastseen) && rec.lastseen != '') ? rec.lastseen : FIELD_NOT_SUPPORTED
356
+ threat = (defined?(rec.threat) && rec.threat != '') ? rec.threat : FIELD_NOT_SUPPORTED
357
+ provider = (defined?(rec.provider) && rec.provider != '') ? rec.provider : FIELD_NOT_SUPPORTED
358
+ fraud_score = (defined?(rec.fraud_score) && rec.fraud_score != '') ? rec.fraud_score : FIELD_NOT_SUPPORTED
359
+ if self.db_index == 1
360
+ isproxy = (rec.country_short == '-') ? 0 : 1
361
+ else
362
+ isproxy = (rec.proxytype == '-') ? 0 : (rec.proxytype == 'DCH' || rec.proxytype == 'SES') ? 2 : 1
363
+ end
364
+ else
365
+ country_short = INVALID_IP_ADDRESS
366
+ country_long = INVALID_IP_ADDRESS
367
+ region = INVALID_IP_ADDRESS
368
+ city = INVALID_IP_ADDRESS
369
+ isp = INVALID_IP_ADDRESS
370
+ proxytype = INVALID_IP_ADDRESS
371
+ domain = INVALID_IP_ADDRESS
372
+ usagetype = INVALID_IP_ADDRESS
373
+ asn = INVALID_IP_ADDRESS
374
+ as = INVALID_IP_ADDRESS
375
+ last_seen = INVALID_IP_ADDRESS
376
+ threat = INVALID_IP_ADDRESS
377
+ provider = INVALID_IP_ADDRESS
378
+ fraud_score = INVALID_IP_ADDRESS
379
+ isproxy = -1
380
+ end
381
+ else
382
+ country_short = INVALID_IP_ADDRESS
383
+ country_long = INVALID_IP_ADDRESS
384
+ region = INVALID_IP_ADDRESS
385
+ city = INVALID_IP_ADDRESS
386
+ isp = INVALID_IP_ADDRESS
387
+ proxytype = INVALID_IP_ADDRESS
388
+ domain = INVALID_IP_ADDRESS
389
+ usagetype = INVALID_IP_ADDRESS
390
+ asn = INVALID_IP_ADDRESS
391
+ as = INVALID_IP_ADDRESS
392
+ last_seen = INVALID_IP_ADDRESS
393
+ threat = INVALID_IP_ADDRESS
394
+ provider = INVALID_IP_ADDRESS
395
+ fraud_score = INVALID_IP_ADDRESS
396
+ isproxy = -1
397
+ end
398
+ results = {}
399
+ results['is_proxy'] = isproxy
400
+ results['proxy_type'] = proxytype
401
+ results['country_short'] = country_short
402
+ results['country_long'] = country_long
403
+ results['region'] = region
404
+ results['city'] = city
405
+ results['isp'] = isp
406
+ results['domain'] = domain
407
+ results['usagetype'] = usagetype
408
+ results['asn'] = asn
409
+ results['as'] = as
410
+ results['last_seen'] = last_seen
411
+ results['threat'] = threat
412
+ results['provider'] = provider
413
+ results['fraud_score'] = fraud_score
414
+ return results
415
+ end
416
+
417
+ def bsearch(low, high, ipnum, base_addr, col_length)
418
+ while low <= high do
419
+ mid = (low + high) >> 1
420
+ ip_from, ip_to = get_from_to(mid, base_addr, col_length)
421
+ if ipnum >= ip_from && ipnum < ip_to
422
+ from_base = ( base_addr + mid * (col_length + (self.v4 ? 0 : 12)))
423
+ file.seek(from_base)
424
+ if v4
425
+ return self.record_class4.read(file)
426
+ else
427
+ return self.record_class6.read(file)
428
+ end
429
+ else
430
+ if ipnum < ip_from
431
+ high = mid - 1
432
+ else
433
+ low = mid + 1
434
+ end
435
+ end
436
+ end
437
+ end
438
+
439
+ def get_from_to(mid, base_addr, col_length)
440
+ from_base = (base_addr + mid * (col_length + (v4 ? 0 : 12)))
441
+ data_length = col_length + (v4 ? 4 : (12 + 16))
442
+ file.seek(from_base)
443
+ data_read = file.read(data_length)
444
+ ip_from = v4 ? data_read[0..3].unpack('V').first : readipv6(data_read[0..15].unpack('V*'))
445
+ ip_to = v4 ? data_read[(data_length - 4)..(data_length - 1)].unpack('V').first : readipv6(data_read[(data_length - 16)..(data_length - 1)].unpack('V*'))
446
+ [ip_from, ip_to]
447
+ end
448
+
449
+ def validateip(ip)
450
+ if ip.ipv4?
451
+ ipv = 4
452
+ ipnum = ip.to_i + 0
453
+ else
454
+ ipv = 6
455
+ ipnum = ip.to_i + 0
456
+ #reformat ipv4 address in ipv6
457
+ if ipnum >= 281470681743360 && ipnum <= 281474976710655
458
+ ipv = 4
459
+ ipnum = ipnum - 281470681743360
460
+ end
461
+ #reformat 6to4 address to ipv4 address 2002:: to 2002:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF
462
+ if ipnum >= 42545680458834377588178886921629466624 && ipnum <= 42550872755692912415807417417958686719
463
+ ipv = 4
464
+ #bitshift right 80 bits
465
+ ipnum = ipnum >> 80
466
+ #bitwise modulus to get the last 32 bit
467
+ ipnum = ipnum % 4294967296
468
+ end
469
+ #reformat Teredo address to ipv4 address 2001:0000:: to 2001:0000:FFFF:FFFF:FFFF:FFFF:FFFF:FFFF:
470
+ if ipnum >= 42540488161975842760550356425300246528 && ipnum <= 42540488241204005274814694018844196863
471
+ ipv = 4
472
+ #bitwise not to invert binary
473
+ ipnum = ~ipnum
474
+ #bitwise modulus to get the last 32 bit
475
+ ipnum = ipnum % 4294967296
476
+ end
477
+ end
478
+ [ipv, ipnum]
479
+ end
480
+
481
+ def read32x2(indexp)
482
+ file.seek(indexp - 1)
483
+ data_read = file.read(8)
484
+ data1 = data_read[0..3].unpack('V').first
485
+ data2 = data_read[4..7].unpack('V').first
486
+ return [data1, data2]
487
+ end
488
+
489
+ def readipv6(parts)
490
+ return parts[0] + parts[1] * 4294967296 + parts[2] * 4294967296**2 + parts[3] * 4294967296**3
491
+ end
492
+
493
+ private :get_record, :bsearch, :get_from_to, :read32x2, :readipv6
494
+
495
+ end
496
+
497
+ class Ip2proxyWebService
498
+ attr_accessor :ws_api_key, :ws_package, :ws_use_ssl
499
+
500
+ def initialize(api_key, package, use_ssl)
501
+ if !api_key.match(/^[0-9A-Z]{10}$/) && api_key != 'demo'
502
+ raise Exception.new "Please provide a valid IP2Proxy web service API key."
503
+ end
504
+ if !package.match(/^PX[0-9]+$/)
505
+ package = 'PX1'
506
+ end
507
+ if use_ssl == ''
508
+ use_ssl = true
509
+ end
510
+ self.ws_api_key = api_key
511
+ self.ws_package = package
512
+ self.ws_use_ssl = use_ssl
513
+ end
514
+
515
+ def lookup(ip)
516
+ if self.ws_use_ssl
517
+ response = Net::HTTP.get(URI("https://api.ip2proxy.com/?key=" + self.ws_api_key + "&ip=" + ip + "&package=" + self.ws_package + "&format=json"))
518
+ else
519
+ response = Net::HTTP.get(URI("http://api.ip2proxy.com/?key=" + self.ws_api_key + "&ip=" + ip + "&package=" + self.ws_package + "&format=json"))
520
+ end
521
+ parsed_response = JSON.parse(response)
522
+ if parsed_response.nil?
523
+ return false
524
+ end
525
+ if parsed_response["response"] != "OK"
526
+ raise Exception.new "Error: " + parsed_response["response"]
527
+ end
528
+ return parsed_response
529
+ end
530
+
531
+ def get_credit()
532
+ if self.ws_use_ssl
533
+ response = Net::HTTP.get(URI("https://api.ip2proxy.com/?key=" + self.ws_api_key + "&check=true"))
534
+ else
535
+ response = Net::HTTP.get(URI("http://api.ip2proxy.com/?key=" + self.ws_api_key + "&check=true"))
536
+ end
537
+ parsed_response = JSON.parse(response)
538
+ if parsed_response.nil?
539
+ return 0
540
+ end
541
+ if parsed_response["response"].nil?
542
+ return 0
543
+ end
544
+ return parsed_response["response"]
545
+ end
527
546
  end