ipip 0.0.0 → 0.0.1

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
  SHA1:
3
- metadata.gz: 4704356089a22fb156e29c7f9ea60bd95cdb8d2c
4
- data.tar.gz: a570df09135777e51d7ce824c152ae08fa90abf1
3
+ metadata.gz: 9bdfbd6d50b7eb795f73a5e4b65a70a0b2ffd9a6
4
+ data.tar.gz: 883aec6cf7852021f58b281a243f5d8c3e64c53d
5
5
  SHA512:
6
- metadata.gz: 015fb4d40652f7848d9e45935c319d80a3105256af407b4d1f795dc7207ae3d0f48622455edd2b18b954a3fd0210fc9f827820e6781fe994ecd1d1de3b8102bc
7
- data.tar.gz: e4fcbecca092e1d1bb93a9e979f861c7f722ae5f27da161c8a2038c21a44db205c99b7d26243dc7b10c6ea5d3bc072ab368287c615b94fc592dbf3653e2d90e8
6
+ metadata.gz: 7b2a4262535d181ad5b833dee9e1d74591ef37ffc3ac1777ab4b92920a0505e236955d95a94b805b5d13b11f26fce196f7caeac3977608754411f5ad96910a33
7
+ data.tar.gz: 43728d7b8021e69a45e1576d4296f6b4519c010e587e652cb110e25e67b9951dca62401ab0973859f047eb049885b46b4565343fa19d5a4eba38150d23de227f
@@ -0,0 +1,15 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ # ipip - IP location search based on ipip.net.
4
+ # usage: ipip [ip | domain]
5
+ #
6
+
7
+ require 'socket'
8
+ require 'ipip'
9
+
10
+ if ip = ARGV[0]
11
+ location = IPIP.find(ip)
12
+ puts "Location for #{ip}: #{location}"
13
+ else
14
+ abort "usage: ipip [ip | domain]"
15
+ end
@@ -1,4 +1,18 @@
1
1
  require 'ipip/version'
2
+ require 'ipip/ipv4_database'
2
3
 
3
4
  module IPIP
5
+
6
+ class << IPIP
7
+
8
+ def find(ip)
9
+ ipv4_database.find(ip)
10
+ end
11
+
12
+ def ipv4_database(data_file=nil)
13
+ @ipv4_database ||= IPv4Database.new(data_file)
14
+ end
15
+
16
+ end
17
+
4
18
  end
Binary file
@@ -0,0 +1,94 @@
1
+ require 'socket'
2
+ require 'ipaddr'
3
+
4
+ module IPIP
5
+
6
+ # Database for search IPv4 address.
7
+ #
8
+ # The IPIP.net data file(17monipdb.dat) format in bytes::
9
+ #
10
+ # ---------------------------
11
+ # | 4 bytes | <- offset number
12
+ # ---------------------------
13
+ # | 256 * 4 bytes | <- first ip number index
14
+ # ---------------------------
15
+ # | offset - 1024 - 4 bytes | <- ip index
16
+ # ---------------------------
17
+ # | data storage |
18
+ # ---------------------------
19
+ #
20
+ class IPv4Database
21
+
22
+ OFFSET_NUMBER_SIZE = 4
23
+ FIRST_IP_NUMBER_INDEX_SIZE = 256 * 4
24
+ IP_BLOCK_SIZE = 8
25
+ DEFAULT_DATA_FILE = File.expand_path("../17monipdb.dat", __FILE__)
26
+
27
+ def initialize(data_file=nil)
28
+ @data_file = data_file || DEFAULT_DATA_FILE
29
+ end
30
+
31
+ def find(ip)
32
+ ip = IPSocket::getaddress(ip)
33
+ lookup_ipv4(ip)
34
+ end
35
+
36
+ private
37
+
38
+ def offset
39
+ @offset ||= unpack_N(binread(OFFSET_NUMBER_SIZE, 0))
40
+ end
41
+
42
+ def buffer
43
+ @buffer ||= binread(nil, OFFSET_NUMBER_SIZE)
44
+ end
45
+
46
+ def binread(length, offset)
47
+ IO.binread(@data_file, length, offset)
48
+ end
49
+
50
+ def lookup_ipv4(ip)
51
+ ip = IPAddr.new(ip)
52
+ return unless ip.ipv4?
53
+
54
+ nip = ip.hton
55
+
56
+ first_ip = unpack_C(nip)
57
+ first_ip_offset = first_ip * 4
58
+
59
+ start = unpack_V(buffer[first_ip_offset, 4])
60
+ start_offset = start * IP_BLOCK_SIZE + FIRST_IP_NUMBER_INDEX_SIZE
61
+
62
+ data_offset = data_length = 0
63
+
64
+ lo, hi = 0, (offset - start_offset) / IP_BLOCK_SIZE
65
+
66
+ while lo < hi
67
+ mid = (lo + hi) / 2
68
+ mid_offset = start_offset + mid * IP_BLOCK_SIZE
69
+ mid_val = buffer[mid_offset, 4]
70
+
71
+ if mid_val < nip
72
+ lo = mid + 1
73
+ else
74
+ hi = mid
75
+ end
76
+ end
77
+
78
+ start_offset += lo * IP_BLOCK_SIZE
79
+ return if start_offset == offset
80
+
81
+ data_offset = unpack_V(buffer[start_offset + 4, 3] + 0.chr)
82
+ data_length = unpack_C(buffer[start_offset + 7])
83
+
84
+ data_offset = offset + data_offset - FIRST_IP_NUMBER_INDEX_SIZE - OFFSET_NUMBER_SIZE
85
+ data = buffer[data_offset, data_length].encode('UTF-8', 'UTF-8')
86
+ end
87
+
88
+ [:C, :N, :V].each do |format|
89
+ define_method "unpack_#{format}" do |binary|
90
+ binary.unpack(format.to_s).first
91
+ end
92
+ end
93
+ end
94
+ end
@@ -1,3 +1,3 @@
1
1
  module IPIP
2
- VERSION = '0.0.0'
2
+ VERSION = '0.0.1'
3
3
  end
metadata CHANGED
@@ -1,22 +1,40 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: ipip
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.0
4
+ version: 0.0.1
5
5
  platform: ruby
6
6
  authors:
7
7
  - liluo
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-09-15 00:00:00.000000000 Z
12
- dependencies: []
11
+ date: 2015-09-27 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rspec
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: '0'
20
+ type: :development
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: '0'
13
27
  description: " IP search based on ipip.net "
14
28
  email: i@liluo.org
15
- executables: []
29
+ executables:
30
+ - ipip
16
31
  extensions: []
17
32
  extra_rdoc_files: []
18
33
  files:
34
+ - bin/ipip
19
35
  - lib/ipip.rb
36
+ - lib/ipip/17monipdb.dat
37
+ - lib/ipip/ipv4_database.rb
20
38
  - lib/ipip/version.rb
21
39
  homepage: https://github.com/liluo/ipip
22
40
  licenses: