oui-offline 1.2.5-java
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 +7 -0
- checksums.yaml.gz.sig +0 -0
- data/Gemfile +8 -0
- data/README.md +113 -0
- data/bin/oui +61 -0
- data/data/oui-manual.json +7 -0
- data/data/oui.txt +128306 -0
- data/db/oui.sqlite3 +0 -0
- data/lib/oui.rb +380 -0
- data/oui-offline.gemspec +40 -0
- data.tar.gz.sig +5 -0
- metadata +141 -0
- metadata.gz.sig +0 -0
data/db/oui.sqlite3
ADDED
Binary file
|
data/lib/oui.rb
ADDED
@@ -0,0 +1,380 @@
|
|
1
|
+
autoload :FileUtils, 'fileutils'
|
2
|
+
autoload :JSON, 'json'
|
3
|
+
require 'monitor'
|
4
|
+
require 'open-uri'
|
5
|
+
|
6
|
+
require 'sequel'
|
7
|
+
|
8
|
+
# Organizationally Unique Identifier
|
9
|
+
module OUI
|
10
|
+
extend self
|
11
|
+
|
12
|
+
private
|
13
|
+
|
14
|
+
DEBUGGING_DEFAULT = false
|
15
|
+
TABLE = :ouis
|
16
|
+
# import data/oui.txt instead of fetching remotely
|
17
|
+
IMPORT_LOCAL_TXT_FILE_DEFAULT = false
|
18
|
+
# use in-memory instead of persistent file
|
19
|
+
IN_MEMORY_ONLY_DEFAULT = false
|
20
|
+
ROOT = File.expand_path(File.join('..', '..'), __FILE__)
|
21
|
+
LOCAL_DB_DEFAULT = File.join(ROOT, 'db', 'oui.sqlite3')
|
22
|
+
LOCAL_TXT_FILE = File.join(ROOT, 'data', 'oui.txt')
|
23
|
+
REMOTE_TXT_URI = 'http://standards.ieee.org/develop/regauth/oui/oui.txt'
|
24
|
+
LOCAL_MANUAL_FILE = File.join(ROOT, 'data', 'oui-manual.json')
|
25
|
+
FIRST_LINE_INDEX = 7
|
26
|
+
EXPECTED_DUPLICATES = [0x0001C8, 0x080030]
|
27
|
+
LINE_LENGTH = 22
|
28
|
+
HEX_BEGINNING_REGEX = /\A[[:space:]]{2}[[:xdigit:]]{2}-/
|
29
|
+
ERASE_LINE = "\b" * LINE_LENGTH
|
30
|
+
BLANK_LINE = ' ' * LINE_LENGTH
|
31
|
+
|
32
|
+
MISSING_COUNTRIES = [
|
33
|
+
0x000052,
|
34
|
+
0x002142,
|
35
|
+
0x684CA8
|
36
|
+
]
|
37
|
+
|
38
|
+
COUNTRY_OVERRIDES = {
|
39
|
+
0x000052 => 'UNITED STATES',
|
40
|
+
0x002142 => 'SERBIA',
|
41
|
+
0x684CA8 => 'CHINA'
|
42
|
+
}
|
43
|
+
|
44
|
+
public
|
45
|
+
|
46
|
+
@@local_db = LOCAL_DB_DEFAULT
|
47
|
+
|
48
|
+
def local_db
|
49
|
+
@@local_db
|
50
|
+
end
|
51
|
+
|
52
|
+
def local_db=(v)
|
53
|
+
@@local_db = v || LOCAL_DB_DEFAULT
|
54
|
+
end
|
55
|
+
|
56
|
+
|
57
|
+
@@debugging = DEBUGGING_DEFAULT
|
58
|
+
|
59
|
+
def debugging
|
60
|
+
@@debugging
|
61
|
+
end
|
62
|
+
|
63
|
+
def debugging=(v)
|
64
|
+
@@debugging = (v.nil?) ? DEBUGGING_DEFAULT : v
|
65
|
+
end
|
66
|
+
|
67
|
+
|
68
|
+
@@import_local_txt_file = IMPORT_LOCAL_TXT_FILE_DEFAULT
|
69
|
+
|
70
|
+
def import_local_txt_file
|
71
|
+
@@import_local_txt_file
|
72
|
+
end
|
73
|
+
|
74
|
+
def import_local_txt_file=(v)
|
75
|
+
@@import_local_txt_file = (v.nil?) ? IMPORT_LOCAL_TXT_FILE_DEFAULT : v
|
76
|
+
end
|
77
|
+
|
78
|
+
|
79
|
+
@@in_memory_only = IN_MEMORY_ONLY_DEFAULT
|
80
|
+
|
81
|
+
def in_memory_only
|
82
|
+
@@in_memory_only
|
83
|
+
end
|
84
|
+
|
85
|
+
def in_memory_only=(v)
|
86
|
+
if v != @@in_memory_only
|
87
|
+
@@in_memory_only = (v.nil?) ? IN_MEMORY_ONLY_DEFAULT : v
|
88
|
+
close_db
|
89
|
+
end
|
90
|
+
end
|
91
|
+
|
92
|
+
# @param oui [String,Integer] hex or numeric OUI to find
|
93
|
+
# @return [Hash,nil]
|
94
|
+
def find(oui)
|
95
|
+
semaphore.synchronize do
|
96
|
+
update_db unless table? && table.count > 0
|
97
|
+
r = table.where(id: self.to_i(oui)).first
|
98
|
+
r.delete :create_table if r # not sure why this is here, but nuking it
|
99
|
+
r
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
# Converts an OUI string to an integer of equal value
|
104
|
+
# @param oui [String,Integer] MAC OUI in hexadecimal formats
|
105
|
+
# hhhh.hh, hh:hh:hh, hh-hh-hh or hhhhhh
|
106
|
+
# @return [Integer] numeric representation of oui
|
107
|
+
def to_i(oui)
|
108
|
+
return oui if oui.is_a? Integer
|
109
|
+
oui = oui.strip.gsub(/[:\- .]/, '')
|
110
|
+
if oui =~ /([[:xdigit:]]{6})/
|
111
|
+
$1.to_i(16)
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
# Convert an id to OUI
|
116
|
+
# @param oui [String,nil] string to place between pairs of hex digits, nil for none
|
117
|
+
# @return [String] hexadecimal format of id
|
118
|
+
def to_s(id, sep = '-')
|
119
|
+
return id if id.is_a? String
|
120
|
+
unless id >= 0x000000 && id <= 0xFFFFFF
|
121
|
+
raise ArgumentError, "#{id} is not a valid 24-bit OUI"
|
122
|
+
end
|
123
|
+
format('%06x', id).scan(/../).join(sep)
|
124
|
+
end
|
125
|
+
|
126
|
+
@@db = nil
|
127
|
+
# Release backend resources
|
128
|
+
def close_db
|
129
|
+
semaphore.synchronize do
|
130
|
+
debug 'Closing database'
|
131
|
+
if @@db
|
132
|
+
@@db.disconnect
|
133
|
+
@@db = nil
|
134
|
+
end
|
135
|
+
end
|
136
|
+
end
|
137
|
+
|
138
|
+
def clear_table
|
139
|
+
debug 'clear_table'
|
140
|
+
table.delete_sql
|
141
|
+
end
|
142
|
+
|
143
|
+
# Update database from fetched URL
|
144
|
+
# @param [Boolean] whether to connect to the network or not
|
145
|
+
# @return [Integer] number of unique records loaded
|
146
|
+
def update_db(local = nil, db_file = nil)
|
147
|
+
semaphore.synchronize do
|
148
|
+
debug "update_db(local = #{local}, db_file = #{db_file})"
|
149
|
+
close_db
|
150
|
+
old_import_local_txt_file = self.import_local_txt_file
|
151
|
+
self.import_local_txt_file = local
|
152
|
+
old_local_db = self.local_db
|
153
|
+
self.local_db = db_file
|
154
|
+
## Sequel
|
155
|
+
debug '--- close db ---'
|
156
|
+
debug '--- close db ---'
|
157
|
+
debug '--- drop table ---'
|
158
|
+
drop_table
|
159
|
+
# debug '--- drop table ---'
|
160
|
+
# debug '--- create table ---'
|
161
|
+
create_table
|
162
|
+
# debug '--- create table ---'
|
163
|
+
db.transaction do
|
164
|
+
debug '--- clear table ---'
|
165
|
+
clear_table
|
166
|
+
debug '--- clear table ---'
|
167
|
+
debug '--- install manual ---'
|
168
|
+
install_manual
|
169
|
+
debug '--- install manual ---'
|
170
|
+
debug '--- install updates ---'
|
171
|
+
install_updates
|
172
|
+
debug '--- install updates ---'
|
173
|
+
end
|
174
|
+
debug '--- close db ---'
|
175
|
+
close_db
|
176
|
+
debug '--- close db ---'
|
177
|
+
|
178
|
+
self.local_db = old_local_db
|
179
|
+
self.import_local_txt_file = old_import_local_txt_file
|
180
|
+
## AR
|
181
|
+
# self.transaction do
|
182
|
+
# self.delete_all
|
183
|
+
# self.install_manual
|
184
|
+
# self.install_updates
|
185
|
+
# end
|
186
|
+
debug "update_db(local = #{local}, db_file = #{db_file}) finish"
|
187
|
+
end
|
188
|
+
end
|
189
|
+
|
190
|
+
private
|
191
|
+
|
192
|
+
def connect_file_db(f)
|
193
|
+
FileUtils.mkdir_p(File.dirname(f))
|
194
|
+
if RUBY_PLATFORM == 'java'
|
195
|
+
u = 'jdbc:sqlite:'+f
|
196
|
+
else
|
197
|
+
u = 'sqlite:'+f
|
198
|
+
end
|
199
|
+
debug "Connecting to db file #{u}"
|
200
|
+
Sequel.connect(u)
|
201
|
+
end
|
202
|
+
|
203
|
+
def connect_db
|
204
|
+
if in_memory_only
|
205
|
+
debug 'Connecting to in-memory database'
|
206
|
+
if RUBY_PLATFORM == 'java'
|
207
|
+
Sequel.connect('jdbc:sqlite::memory:')
|
208
|
+
else
|
209
|
+
Sequel.sqlite # in-memory sqlite database
|
210
|
+
end
|
211
|
+
else
|
212
|
+
connect_file_db local_db
|
213
|
+
end
|
214
|
+
end
|
215
|
+
|
216
|
+
def db
|
217
|
+
@@db ||= connect_db
|
218
|
+
end
|
219
|
+
|
220
|
+
def table?
|
221
|
+
db.tables.include? TABLE
|
222
|
+
end
|
223
|
+
|
224
|
+
def table
|
225
|
+
db[TABLE]
|
226
|
+
end
|
227
|
+
|
228
|
+
def drop_table
|
229
|
+
debug 'drop_table'
|
230
|
+
db.drop_table(TABLE) if table?
|
231
|
+
end
|
232
|
+
|
233
|
+
def create_table
|
234
|
+
# debug 'create_table'
|
235
|
+
db.create_table TABLE do
|
236
|
+
primary_key :id
|
237
|
+
String :organization, null: false
|
238
|
+
String :address1
|
239
|
+
String :address2
|
240
|
+
String :address3
|
241
|
+
String :country
|
242
|
+
index :id
|
243
|
+
end
|
244
|
+
end
|
245
|
+
|
246
|
+
# @param lines [Array<String>]
|
247
|
+
# @return [Array<Array<String>>]
|
248
|
+
def parse_lines_into_groups(lines)
|
249
|
+
grps, curgrp = [], []
|
250
|
+
lines[FIRST_LINE_INDEX..-1].each do |line|
|
251
|
+
if !curgrp.empty? && line =~ HEX_BEGINNING_REGEX
|
252
|
+
grps << curgrp
|
253
|
+
curgrp = []
|
254
|
+
end
|
255
|
+
line.strip!
|
256
|
+
next if line.empty?
|
257
|
+
curgrp << line
|
258
|
+
end
|
259
|
+
grps << curgrp # add last group and return
|
260
|
+
end
|
261
|
+
|
262
|
+
# @param g [Array<String>]
|
263
|
+
def parse_org(g)
|
264
|
+
g[0].split("\t").last
|
265
|
+
end
|
266
|
+
|
267
|
+
# @param g [Array<String>]
|
268
|
+
def parse_id(g)
|
269
|
+
g[1].split(' ')[0].to_i(16)
|
270
|
+
end
|
271
|
+
|
272
|
+
def parse_address1(g)
|
273
|
+
g[2] if g.length >= 4
|
274
|
+
end
|
275
|
+
|
276
|
+
def parse_address2(g, id)
|
277
|
+
g[3] if g.length >= 5 || MISSING_COUNTRIES.include?(id)
|
278
|
+
end
|
279
|
+
|
280
|
+
def parse_address3(g)
|
281
|
+
g[4] if g.length == 6
|
282
|
+
end
|
283
|
+
|
284
|
+
# @param g [Array<String>]
|
285
|
+
# @param id [Integer]
|
286
|
+
def parse_country(g, id)
|
287
|
+
c = COUNTRY_OVERRIDES[id] || g[-1]
|
288
|
+
c if c !~ /\A\h/
|
289
|
+
end
|
290
|
+
|
291
|
+
# @param g [Array<String>]
|
292
|
+
def create_from_line_group(g)
|
293
|
+
n = g.length
|
294
|
+
raise ArgumentError, "Parse error lines: #{n}" unless (2..6).include? n
|
295
|
+
id = parse_id(g)
|
296
|
+
create_unless_present(id: id, organization: parse_org(g),
|
297
|
+
address1: parse_address1(g),
|
298
|
+
address2: parse_address2(g, id),
|
299
|
+
address3: parse_address3(g),
|
300
|
+
country: parse_country(g, id))
|
301
|
+
end
|
302
|
+
|
303
|
+
def fetch
|
304
|
+
uri = oui_uri
|
305
|
+
$stderr.puts "Fetching #{uri}"
|
306
|
+
open(uri).read
|
307
|
+
end
|
308
|
+
|
309
|
+
def install_manual
|
310
|
+
debug 'install_manual'
|
311
|
+
JSON.load(File.read(LOCAL_MANUAL_FILE)).each do |g|
|
312
|
+
# convert keys to symbols
|
313
|
+
g = g.map { |k, v| [k.to_sym, v] }
|
314
|
+
g = Hash[g]
|
315
|
+
# convert OUI octets to integers
|
316
|
+
g[:id] = self.to_i(g[:id])
|
317
|
+
create_unless_present(g)
|
318
|
+
end
|
319
|
+
rescue Errno::ENOENT
|
320
|
+
end
|
321
|
+
|
322
|
+
def install_updates
|
323
|
+
debug 'install_updates'
|
324
|
+
lines = fetch.split("\n").map { |x| x.sub(/\r$/, '') }
|
325
|
+
parse_lines_into_groups(lines).each_with_index do |group, idx|
|
326
|
+
create_from_line_group(group)
|
327
|
+
debug "#{ERASE_LINE}Created records #{idx}" if idx % 1000 == 0
|
328
|
+
end.count
|
329
|
+
debug "#{ERASE_LINE}#{BLANK_LINE}"
|
330
|
+
end
|
331
|
+
|
332
|
+
# Expected duplicates are 00-01-C8 (2x) and 08-00-30 (3x)
|
333
|
+
def expected_duplicate?(id)
|
334
|
+
EXPECTED_DUPLICATES.include? id
|
335
|
+
end
|
336
|
+
|
337
|
+
# Has a particular id been added yet?
|
338
|
+
def added
|
339
|
+
@@added ||= {}
|
340
|
+
end
|
341
|
+
|
342
|
+
def debug?
|
343
|
+
$DEBUG || debugging || ENV['DEBUG_OUI']
|
344
|
+
end
|
345
|
+
|
346
|
+
def debug(*args)
|
347
|
+
$stderr.puts(*args) if debug?
|
348
|
+
end
|
349
|
+
|
350
|
+
def debug_print(*args)
|
351
|
+
$stderr.print(*args) if debug?
|
352
|
+
end
|
353
|
+
|
354
|
+
def semaphore
|
355
|
+
@@semaphore ||= Monitor.new
|
356
|
+
end
|
357
|
+
|
358
|
+
def create_unless_present(opts)
|
359
|
+
id = opts[:id]
|
360
|
+
if added[id]
|
361
|
+
unless expected_duplicate? id
|
362
|
+
debug "OUI unexpected duplicate #{opts}"
|
363
|
+
end
|
364
|
+
else
|
365
|
+
table.insert(opts)
|
366
|
+
# self.create! opts
|
367
|
+
added[id] = true
|
368
|
+
end
|
369
|
+
end
|
370
|
+
|
371
|
+
def oui_uri
|
372
|
+
if import_local_txt_file
|
373
|
+
debug 'oui_uri = local'
|
374
|
+
LOCAL_TXT_FILE
|
375
|
+
else
|
376
|
+
debug 'oui_uri = remote'
|
377
|
+
REMOTE_TXT_URI
|
378
|
+
end
|
379
|
+
end
|
380
|
+
end
|
data/oui-offline.gemspec
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
Gem::Specification::new do |s|
|
2
|
+
s.name = 'oui-offline'
|
3
|
+
s.version = '1.2.5'
|
4
|
+
s.summary = 'Organizationally Unique Idenitfiers (OUI)'
|
5
|
+
s.description = 'Organizationally Unique Idenitfiers (OUI) offline database'
|
6
|
+
s.license = 'MIT'
|
7
|
+
|
8
|
+
s.files =
|
9
|
+
['Gemfile',
|
10
|
+
'README.md',
|
11
|
+
'bin/oui',
|
12
|
+
'data/oui-manual.json',
|
13
|
+
'db/oui.sqlite3',
|
14
|
+
'lib/oui.rb',
|
15
|
+
'oui-offline.gemspec',
|
16
|
+
]
|
17
|
+
s.files << 'data/oui.txt' if File.exist?('data/oui.txt')
|
18
|
+
|
19
|
+
s.required_ruby_version = '>= 1.9.3'
|
20
|
+
|
21
|
+
s.require_path = 'lib'
|
22
|
+
s.executables << 'oui'
|
23
|
+
|
24
|
+
s.author = 'Barry Allard'
|
25
|
+
s.email = 'barry.allard@gmail.com'
|
26
|
+
s.homepage = 'https://github.com/steakknife/oui'
|
27
|
+
s.post_install_message = 'Oui!'
|
28
|
+
|
29
|
+
s.add_dependency 'sequel', '~> 4'
|
30
|
+
if RUBY_PLATFORM == 'java'
|
31
|
+
s.platform = 'java'
|
32
|
+
s.add_dependency 'jdbc-sqlite3'
|
33
|
+
else
|
34
|
+
s.platform = Gem::Platform::RUBY
|
35
|
+
s.add_dependency 'sqlite3', '~> 1'
|
36
|
+
end
|
37
|
+
s.add_development_dependency 'rake', '~> 10'
|
38
|
+
s.add_development_dependency 'minitest', '~> 5'
|
39
|
+
end
|
40
|
+
.tap {|gem| pk = File.expand_path(File.join('~/.keys', 'gem-private_key.pem')); gem.signing_key = pk if File.exist? pk; gem.cert_chain = ['gem-public_cert.pem']} # pressed firmly by waxseal
|
data.tar.gz.sig
ADDED
@@ -0,0 +1,5 @@
|
|
1
|
+
8=�%)�Gk�!���厶9�� ]`�,��N�Q+�ŠՉ��d`"=�Hc
|
2
|
+
�� ������Ҵ丶8]���[�-����h�c/��?��l�������
|
3
|
+
��3�RB*��S��&0<iw�7�G<-�7w4�������&�*�����o�:\T�m#@���|n�'�fn��Z?��P�4��ı�i�1�V����h(Z�X�n����B<�L3�e�v�Ή�����2�Ja�F%<�̺��^�r�o�r��8c�#Z�����eP����W�,NB���[�6脅K�=��!��֕�ҸV�6n˯��#
|
4
|
+
s�_��r�)S�I���Z&��N����h9��ƌ �A�G����a�4E i��1p-�6:������\�^�"4js?ƞ��mF����-(��������B��s��?�B�|�r^�"
|
5
|
+
�C=:i��g��8��z1��[l����̥�~H�ҵP<���҇�z��
|
metadata
ADDED
@@ -0,0 +1,141 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: oui-offline
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 1.2.5
|
5
|
+
platform: java
|
6
|
+
authors:
|
7
|
+
- Barry Allard
|
8
|
+
autorequire:
|
9
|
+
bindir: bin
|
10
|
+
cert_chain:
|
11
|
+
- |
|
12
|
+
-----BEGIN CERTIFICATE-----
|
13
|
+
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
|
42
|
+
t/HWh1yhriCUe/y8+De8M87btOs=
|
43
|
+
-----END CERTIFICATE-----
|
44
|
+
date: 2015-01-27 00:00:00.000000000 Z
|
45
|
+
dependencies:
|
46
|
+
- !ruby/object:Gem::Dependency
|
47
|
+
requirement: !ruby/object:Gem::Requirement
|
48
|
+
requirements:
|
49
|
+
- - ~>
|
50
|
+
- !ruby/object:Gem::Version
|
51
|
+
version: '4'
|
52
|
+
name: sequel
|
53
|
+
prerelease: false
|
54
|
+
type: :runtime
|
55
|
+
version_requirements: !ruby/object:Gem::Requirement
|
56
|
+
requirements:
|
57
|
+
- - ~>
|
58
|
+
- !ruby/object:Gem::Version
|
59
|
+
version: '4'
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
requirement: !ruby/object:Gem::Requirement
|
62
|
+
requirements:
|
63
|
+
- - '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
name: jdbc-sqlite3
|
67
|
+
prerelease: false
|
68
|
+
type: :runtime
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
requirement: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - ~>
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '10'
|
80
|
+
name: rake
|
81
|
+
prerelease: false
|
82
|
+
type: :development
|
83
|
+
version_requirements: !ruby/object:Gem::Requirement
|
84
|
+
requirements:
|
85
|
+
- - ~>
|
86
|
+
- !ruby/object:Gem::Version
|
87
|
+
version: '10'
|
88
|
+
- !ruby/object:Gem::Dependency
|
89
|
+
requirement: !ruby/object:Gem::Requirement
|
90
|
+
requirements:
|
91
|
+
- - ~>
|
92
|
+
- !ruby/object:Gem::Version
|
93
|
+
version: '5'
|
94
|
+
name: minitest
|
95
|
+
prerelease: false
|
96
|
+
type: :development
|
97
|
+
version_requirements: !ruby/object:Gem::Requirement
|
98
|
+
requirements:
|
99
|
+
- - ~>
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '5'
|
102
|
+
description: Organizationally Unique Idenitfiers (OUI) offline database
|
103
|
+
email: barry.allard@gmail.com
|
104
|
+
executables:
|
105
|
+
- oui
|
106
|
+
extensions: []
|
107
|
+
extra_rdoc_files: []
|
108
|
+
files:
|
109
|
+
- Gemfile
|
110
|
+
- README.md
|
111
|
+
- bin/oui
|
112
|
+
- data/oui-manual.json
|
113
|
+
- db/oui.sqlite3
|
114
|
+
- lib/oui.rb
|
115
|
+
- oui-offline.gemspec
|
116
|
+
- data/oui.txt
|
117
|
+
homepage: https://github.com/steakknife/oui
|
118
|
+
licenses:
|
119
|
+
- MIT
|
120
|
+
metadata: {}
|
121
|
+
post_install_message: Oui!
|
122
|
+
rdoc_options: []
|
123
|
+
require_paths:
|
124
|
+
- lib
|
125
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
126
|
+
requirements:
|
127
|
+
- - '>='
|
128
|
+
- !ruby/object:Gem::Version
|
129
|
+
version: 1.9.3
|
130
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
131
|
+
requirements:
|
132
|
+
- - '>='
|
133
|
+
- !ruby/object:Gem::Version
|
134
|
+
version: '0'
|
135
|
+
requirements: []
|
136
|
+
rubyforge_project:
|
137
|
+
rubygems_version: 2.1.9
|
138
|
+
signing_key:
|
139
|
+
specification_version: 4
|
140
|
+
summary: Organizationally Unique Idenitfiers (OUI)
|
141
|
+
test_files: []
|
metadata.gz.sig
ADDED
Binary file
|