mac_vendor 0.0.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/.gitignore +24 -0
- data/LICENSE.txt +21 -0
- data/README.rdoc +38 -0
- data/Rakefile +8 -0
- data/data/oui.txt.gz +0 -0
- data/lib/mac_vendor.rb +90 -0
- data/mac_vendor.gemspec +16 -0
- data/test/test_mac_vendor.rb +57 -0
- metadata +54 -0
data/.gitignore
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
*.gem
|
2
|
+
*.rbc
|
3
|
+
.bundle
|
4
|
+
.config
|
5
|
+
coverage
|
6
|
+
InstalledFiles
|
7
|
+
lib/bundler/man
|
8
|
+
pkg
|
9
|
+
rdoc
|
10
|
+
spec/reports
|
11
|
+
test/tmp
|
12
|
+
test/version_tmp
|
13
|
+
tmp
|
14
|
+
|
15
|
+
# YARD artifacts
|
16
|
+
.yardoc
|
17
|
+
_yardoc
|
18
|
+
doc/
|
19
|
+
|
20
|
+
# Ignore Emacs backups everywhere.
|
21
|
+
*~
|
22
|
+
|
23
|
+
# Ignore textmate projects
|
24
|
+
*.tmproj
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,21 @@
|
|
1
|
+
Copyright (c) 2013 Uceem Idaho, Inc.
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
21
|
+
|
data/README.rdoc
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
= mac_vendor
|
2
|
+
|
3
|
+
* {Homepage}[https://github.com/uceem/mac_vendor.git]
|
4
|
+
* {Email}[mailto:doug at uceem.com]
|
5
|
+
|
6
|
+
== Description
|
7
|
+
|
8
|
+
Given a MAC address, lookup the vendor of the interface.
|
9
|
+
|
10
|
+
Inspired by the Net-MAC-Vendor perl package.
|
11
|
+
|
12
|
+
== Examples
|
13
|
+
|
14
|
+
require 'mac_vendor'
|
15
|
+
|
16
|
+
v = MacVendor.new
|
17
|
+
v.lookup '00-11-22-33-44-55'
|
18
|
+
|
19
|
+
To preload all data up front:
|
20
|
+
|
21
|
+
v = MacVendor.new
|
22
|
+
v.preload_cache
|
23
|
+
v.lookup '00:ff:bb:11:22:33'
|
24
|
+
|
25
|
+
To use a local copy of the data, as of the gem release date:
|
26
|
+
|
27
|
+
v = MacVendor.new :use_local => true
|
28
|
+
v.lookup 'aabbccddeeff'
|
29
|
+
|
30
|
+
== Install
|
31
|
+
|
32
|
+
$ gem install mac_vendor
|
33
|
+
|
34
|
+
== Copyright
|
35
|
+
|
36
|
+
Copyright (c) 2013 Uceem Idaho, Inc.
|
37
|
+
|
38
|
+
See LICENSE.txt for details.
|
data/Rakefile
ADDED
data/data/oui.txt.gz
ADDED
Binary file
|
data/lib/mac_vendor.rb
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'net/http'
|
2
|
+
|
3
|
+
class MacVendor
|
4
|
+
OUI_FULL_URL = 'http://standards.ieee.org/develop/regauth/oui/oui.txt'
|
5
|
+
OUI_SINGLE_URL = 'http://standards.ieee.org/cgi-bin/ouisearch?' # ex: http://standards.ieee.org/cgi-bin/ouisearch?00-11-22
|
6
|
+
|
7
|
+
def initialize(opts={})
|
8
|
+
@prefix_cache = {}
|
9
|
+
@preloaded = false
|
10
|
+
@network_hits = 0 if opts[:enable_network_tracking]
|
11
|
+
preload_cache_via_local_data if opts[:use_local]
|
12
|
+
end
|
13
|
+
|
14
|
+
def lookup(mac)
|
15
|
+
prefix = self.normalize_prefix mac
|
16
|
+
return @prefix_cache[prefix] if @preloaded or @prefix_cache.has_key?(prefix)
|
17
|
+
@prefix_cache[prefix] = fetch_single(prefix)
|
18
|
+
end
|
19
|
+
|
20
|
+
# Attempts to turn anything MAC-like into the first six digits, e.g.: AABBCC
|
21
|
+
def normalize_prefix(mac)
|
22
|
+
mac.strip.upcase.gsub(/^0[xX]/,'').gsub(/[^0-9A-F]/,'')[0..5]
|
23
|
+
end
|
24
|
+
|
25
|
+
# Converts a normalized prefix into something with hyphens, e.g.: AA-BB-CC
|
26
|
+
def hyphen_prefix(p)
|
27
|
+
"#{p[0..1]}-#{p[2..3]}-#{p[4..5]}"
|
28
|
+
end
|
29
|
+
|
30
|
+
def get_url(url)
|
31
|
+
@network_hits +=1 unless @network_hits.nil?
|
32
|
+
Net::HTTP.get URI(url)
|
33
|
+
end
|
34
|
+
|
35
|
+
def fetch_single(prefix)
|
36
|
+
single_txt = get_url OUI_SINGLE_URL + hyphen_prefix(prefix)
|
37
|
+
|
38
|
+
if single_txt =~ /The public OUI listing contains no match for the query/
|
39
|
+
return @prefix_cache[prefix] = nil
|
40
|
+
end
|
41
|
+
|
42
|
+
if single_txt.gsub(/[\r\n]/,"\t") =~ /([0-9A-F]+)\s+\(base 16\)(.*?)pre/
|
43
|
+
mac_prefix = normalize_prefix $1
|
44
|
+
lines = $2.strip.split("\t")
|
45
|
+
company_name = lines[0]
|
46
|
+
company_address = lines[1..-2].reject {|x| x == ''}
|
47
|
+
|
48
|
+
return @prefix_cache[prefix] = {:name => company_name, :address => company_address}
|
49
|
+
end
|
50
|
+
nil
|
51
|
+
end
|
52
|
+
|
53
|
+
def preload_cache_via_string(oui_txt)
|
54
|
+
# First entry is a header
|
55
|
+
entries = oui_txt.split("\n\n")
|
56
|
+
|
57
|
+
entries[1..-1].each do |entry|
|
58
|
+
base16_fields = entry.strip.split("\n")[1].split("\t")
|
59
|
+
mac_prefix = base16_fields[0][0..5]
|
60
|
+
company_name = base16_fields[-1]
|
61
|
+
company_address = entry.strip.gsub("\t",'').split("\n")[2..-1]
|
62
|
+
|
63
|
+
# This actually happens three times in the current dataset!
|
64
|
+
unless @prefix_cache[mac_prefix].nil?
|
65
|
+
#puts "MAC PREFIX COLLISION: #{mac_prefix}"
|
66
|
+
#puts "CURRENT = #{@prefix_cache[mac_prefix].inspect}"
|
67
|
+
#puts "NEW = #{{:name => company_name, :address => company_address}.inspect}"
|
68
|
+
#raise "MAC prefix key collision: #{mac_prefix}"
|
69
|
+
next
|
70
|
+
end
|
71
|
+
|
72
|
+
@prefix_cache[mac_prefix] = {:name => company_name, :address => company_address}
|
73
|
+
end
|
74
|
+
@preloaded = true
|
75
|
+
end
|
76
|
+
|
77
|
+
def preload_cache_via_local_data
|
78
|
+
local_path = File.expand_path(File.dirname(__FILE__) + "/../data/oui.txt.gz")
|
79
|
+
preload_cache_via_string Zlib::GzipReader.open(local_path).read
|
80
|
+
end
|
81
|
+
|
82
|
+
def preload_cache
|
83
|
+
preload_cache_via_string get_url(OUI_FULL_URL)
|
84
|
+
end
|
85
|
+
|
86
|
+
def network_hits
|
87
|
+
@network_hits
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
data/mac_vendor.gemspec
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
Gem::Specification.new do |s|
|
2
|
+
s.name = 'mac_vendor'
|
3
|
+
s.version = '0.0.0'
|
4
|
+
s.date = '2013-01-09'
|
5
|
+
s.license = "MIT"
|
6
|
+
s.summary = "MAC address vendor lookup"
|
7
|
+
s.description = "Given a MAC address, lookup the vendor of the interface."
|
8
|
+
s.authors = ["Doug Wiegley"]
|
9
|
+
s.email = 'doug@uceem.com'
|
10
|
+
|
11
|
+
s.files = `git ls-files`.split($/)
|
12
|
+
s.test_files = s.files.grep(%r{^(test|spec|features)/})
|
13
|
+
s.require_paths = ['lib']
|
14
|
+
|
15
|
+
s.homepage = 'https://github.com/uceem/mac_vendor.git'
|
16
|
+
end
|
@@ -0,0 +1,57 @@
|
|
1
|
+
require 'test/unit'
|
2
|
+
require 'mac_vendor'
|
3
|
+
|
4
|
+
class MacVendorTest < Test::Unit::TestCase
|
5
|
+
def setup
|
6
|
+
@x = { :name=> "CIMSYS Inc",
|
7
|
+
:address=> ["#301,Sinsung-clean BLDG,140, Nongseo-Ri,Kiheung-Eup",
|
8
|
+
"Yongin-City Kyunggi-Do 449-711",
|
9
|
+
"KOREA, REPUBLIC OF"] }
|
10
|
+
@v = MacVendor.new :enable_network_tracking => true
|
11
|
+
end
|
12
|
+
|
13
|
+
def test_normalize_prefix
|
14
|
+
[ 'aa-11-bb', 'aa:11:bb:22:cc:33', 'AA11BBCCDD22', 'aa-11-bb-00-00-00' ].each do |s|
|
15
|
+
assert_equal @v.normalize_prefix(s), 'AA11BB'
|
16
|
+
end
|
17
|
+
assert_equal @v.normalize_prefix('junk'), ''
|
18
|
+
assert_equal @v.network_hits, 0
|
19
|
+
end
|
20
|
+
|
21
|
+
def test_hyphen_prefix
|
22
|
+
assert_equal @v.hyphen_prefix('AA11BB'), 'AA-11-BB'
|
23
|
+
assert_equal @v.hyphen_prefix('junk'), 'ju-nk-'
|
24
|
+
assert_equal @v.network_hits, 0
|
25
|
+
end
|
26
|
+
|
27
|
+
def test_fetch_single
|
28
|
+
assert_equal @v.lookup('00:11:22:33:44:55'), @x
|
29
|
+
assert_equal @v.lookup('00-11-22-33-44-55'), @x
|
30
|
+
assert_equal @v.network_hits, 1
|
31
|
+
end
|
32
|
+
|
33
|
+
def test_fetch_single_not_found
|
34
|
+
assert_equal @v.lookup('FF:FF:FF:33:44:55'), nil
|
35
|
+
assert_equal @v.lookup('FF-FF-FF-33-44-55'), nil
|
36
|
+
assert_equal @v.network_hits, 1
|
37
|
+
end
|
38
|
+
|
39
|
+
def test_preloaded_local
|
40
|
+
mv = MacVendor.new :enable_network_tracking => true, :use_local => true
|
41
|
+
assert_equal mv.network_hits, 0
|
42
|
+
assert_equal mv.lookup('00-11-22-33-44-55'), @x
|
43
|
+
assert_equal mv.network_hits, 0
|
44
|
+
assert_equal mv.lookup('FF-FF-FF-33-44-55'), nil
|
45
|
+
assert_equal mv.network_hits, 0
|
46
|
+
end
|
47
|
+
|
48
|
+
def test_preloaded
|
49
|
+
@v.preload_cache
|
50
|
+
assert_equal @v.network_hits, 1
|
51
|
+
assert_equal @v.lookup('00-11-22-33-44-55'), @x
|
52
|
+
assert_equal @v.network_hits, 1
|
53
|
+
assert_equal @v.lookup('FF-FF-FF-33-44-55'), nil
|
54
|
+
assert_equal @v.network_hits, 1
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
metadata
ADDED
@@ -0,0 +1,54 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mac_vendor
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.0
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Doug Wiegley
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-01-09 00:00:00.000000000Z
|
13
|
+
dependencies: []
|
14
|
+
description: Given a MAC address, lookup the vendor of the interface.
|
15
|
+
email: doug@uceem.com
|
16
|
+
executables: []
|
17
|
+
extensions: []
|
18
|
+
extra_rdoc_files: []
|
19
|
+
files:
|
20
|
+
- .gitignore
|
21
|
+
- LICENSE.txt
|
22
|
+
- README.rdoc
|
23
|
+
- Rakefile
|
24
|
+
- data/oui.txt.gz
|
25
|
+
- lib/mac_vendor.rb
|
26
|
+
- mac_vendor.gemspec
|
27
|
+
- test/test_mac_vendor.rb
|
28
|
+
homepage: https://github.com/uceem/mac_vendor.git
|
29
|
+
licenses:
|
30
|
+
- MIT
|
31
|
+
post_install_message:
|
32
|
+
rdoc_options: []
|
33
|
+
require_paths:
|
34
|
+
- lib
|
35
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
36
|
+
none: false
|
37
|
+
requirements:
|
38
|
+
- - ! '>='
|
39
|
+
- !ruby/object:Gem::Version
|
40
|
+
version: '0'
|
41
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
42
|
+
none: false
|
43
|
+
requirements:
|
44
|
+
- - ! '>='
|
45
|
+
- !ruby/object:Gem::Version
|
46
|
+
version: '0'
|
47
|
+
requirements: []
|
48
|
+
rubyforge_project:
|
49
|
+
rubygems_version: 1.8.17
|
50
|
+
signing_key:
|
51
|
+
specification_version: 3
|
52
|
+
summary: MAC address vendor lookup
|
53
|
+
test_files:
|
54
|
+
- test/test_mac_vendor.rb
|