mac_vendor 0.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,8 @@
1
+ require 'rake/testtask'
2
+
3
+ Rake::TestTask.new do |t|
4
+ t.libs << 'test'
5
+ end
6
+
7
+ desc "Run tests"
8
+ task :default => :test
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
+
@@ -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