mac_address_eui48 0.1.0 → 0.1.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.
- data/README.md +69 -20
- data/bin/benchmark.rb +16 -0
- data/bin/gen_mac_address.rb +58 -0
- data/bin/oui_lookup.rb +30 -0
- data/lib/mac_address_eui48.rb +7 -7
- data/lib/mac_address_eui48/mac_address.rb +22 -17
- data/lib/mac_address_eui48/oui_resolver.rb +30 -16
- data/lib/mac_address_eui48/version.rb +2 -2
- metadata +8 -2
data/README.md
CHANGED
@@ -1,36 +1,85 @@
|
|
1
1
|
# MacAddressEui48
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
3
|
+
This is an implementation of MAC address along with tools for OUI lookup and random MAC address generation. It can be used as a Ruby library or through the command line tools.
|
4
|
+
|
5
|
+
The OUI resolver is based on the official OUI file provided by the IEEE http://standards-oui.ieee.org/oui.txt. This file is stored in `data/`.
|
6
|
+
|
7
|
+
## Features
|
8
|
+
### Command line tools
|
9
|
+
|
10
|
+
* gen_mac_address.rb: generate random MAC address
|
11
|
+
* Fully random address
|
12
|
+
* Generate multiple address at one time
|
13
|
+
* Address with registered OUI
|
14
|
+
* Address with given OUI
|
15
|
+
* oui_lookup.rb: resolve OUI of MAC address
|
16
|
+
|
17
|
+
### Library
|
18
|
+
|
19
|
+
|
20
|
+
* MacAddressEui48::MacAddress
|
21
|
+
* Initialization from Integer, String of MacAddress
|
22
|
+
* Comparison operator
|
23
|
+
* Iteration over a range of MacAddress
|
24
|
+
* Test for Broadcast address
|
25
|
+
* Flag tests: locally administered, multicast, ...
|
26
|
+
|
27
|
+
* MacAddressEui48::OuiResolver
|
28
|
+
* Lookup: Organization/Vendor from MAC address
|
29
|
+
* Reverse lookup: OUI (MAC prefix) from Organization/Vendor
|
30
|
+
* Random MAC address generation
|
31
|
+
* Over all space (2^48 values)
|
32
|
+
* Only within space of registered OUI
|
33
|
+
* Over a specific OUI
|
34
|
+
|
7
35
|
## Installation
|
8
36
|
|
9
|
-
|
10
|
-
|
11
|
-
```ruby
|
12
|
-
gem 'mac_address_eui48'
|
37
|
+
```bash
|
38
|
+
gem install mac_address_eui48
|
13
39
|
```
|
14
40
|
|
15
|
-
|
16
|
-
|
17
|
-
$ bundle
|
41
|
+
## Usage
|
18
42
|
|
19
|
-
|
43
|
+
### Command line tools
|
44
|
+
|
45
|
+
Generation of random MAC address
|
46
|
+
```bash
|
47
|
+
# fully random address
|
48
|
+
$ ./gen_mac_address.rb
|
49
|
+
5A:79:5A:7D:FC:71
|
50
|
+
|
51
|
+
# random address in with registered OUI
|
52
|
+
$ ./gen_mac_address.rb -r
|
53
|
+
00:1C:AE:57:0E:BA
|
54
|
+
|
55
|
+
# multiple address
|
56
|
+
$ ./gen_mac_address.rb -n 5
|
57
|
+
3F:40:DC:4B:CC:EB
|
58
|
+
49:23:BC:D4:54:9D
|
59
|
+
85:F6:49:BB:CC:47
|
60
|
+
33:68:8A:9E:21:57
|
61
|
+
42:B6:80:B8:B0:7F
|
62
|
+
|
63
|
+
# random mac address from a given OUI (vendor)
|
64
|
+
$ ./gen_mac_address.rb -o "Xerox Corporation"
|
65
|
+
9C:93:4E:27:2A:16
|
66
|
+
```
|
20
67
|
|
21
|
-
|
68
|
+
Resolving OUI
|
69
|
+
```bash
|
70
|
+
$ ./oui_lookup.rb C4:04:15:12:34:56
|
71
|
+
NETGEAR INC.,
|
72
|
+
```
|
73
|
+
|
74
|
+
### Library
|
22
75
|
|
23
|
-
|
76
|
+
TODO
|
24
77
|
|
25
|
-
TODO: Write usage instructions here
|
26
78
|
|
27
79
|
## Development
|
28
|
-
|
29
|
-
After checking out the repo, run `bin/setup` to install dependencies. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
|
30
|
-
|
31
|
-
To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
|
80
|
+
TODO
|
32
81
|
|
33
82
|
## Contributing
|
34
83
|
|
35
|
-
Bug reports and pull requests are welcome on GitHub at https://github.com/
|
84
|
+
Bug reports and pull requests are welcome on GitHub at https://github.com/cunchem/mac_address_eui48. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](contributor-covenant.org) code of conduct.
|
36
85
|
|
data/bin/benchmark.rb
ADDED
@@ -0,0 +1,16 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>
|
3
|
+
|
4
|
+
require 'benchmark'
|
5
|
+
require 'mac_address_eui48.rb'
|
6
|
+
|
7
|
+
n = 50
|
8
|
+
Benchmark.bm(25) do |x|
|
9
|
+
resolver = MacAddressEui48::OuiResolver.new()
|
10
|
+
x.report("Init Resolver :") {resolver = MacAddressEui48::OuiResolver.new()}
|
11
|
+
x.report("random_mac (#{n} times):") { n.times do resolver.random_mac; end }
|
12
|
+
x.report("random_oui_mac (#{n} times):") { n.times do resolver.random_oui_mac; end }
|
13
|
+
x.report("random_mac_vendor(#{n} times):") { n.times do resolver.random_mac_vendor("Apple, Inc."); end }
|
14
|
+
x.report("oui_lookup (#{n} times):") { n.times do resolver.oui_lookup(resolver.random_mac); end }
|
15
|
+
x.report("reverse_lookup (#{n} times):") { n.times do resolver.reverse_lookup(resolver.oui_lookup(resolver.random_mac)); end }
|
16
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>
|
3
|
+
require 'mac_address_eui48.rb'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: gen_mac_address.rb [options]
|
9
|
+
gen_mac_address (mac_address_eui4)
|
10
|
+
Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>"
|
11
|
+
|
12
|
+
|
13
|
+
options[:verbose] = false
|
14
|
+
opts.on("-v", "--[no-]verbose", "Run verbosely") do
|
15
|
+
options[:verbose] = true
|
16
|
+
end
|
17
|
+
|
18
|
+
options[:oui] = nil
|
19
|
+
opts.on("-o OUI", "--oui OUI", "OUI (Oragnization Unique Identifier)") do |v|
|
20
|
+
options[:oui] = v
|
21
|
+
end
|
22
|
+
|
23
|
+
options[:registered] = false
|
24
|
+
opts.on("-r", "--registered", "Generate random MAC from registered OUIs (disabled by default)") do |v|
|
25
|
+
options[:registered] = true
|
26
|
+
end
|
27
|
+
|
28
|
+
options[:number] = 1
|
29
|
+
opts.on("-n N", "--number N", "Number of MAC address to generate") do |v|
|
30
|
+
options[:number] = v
|
31
|
+
end
|
32
|
+
|
33
|
+
options[:help] = false
|
34
|
+
opts.on("-h", "--help", "Show this help") do
|
35
|
+
puts opts
|
36
|
+
exit
|
37
|
+
options[:help] = true
|
38
|
+
end
|
39
|
+
end.parse!
|
40
|
+
|
41
|
+
#p options
|
42
|
+
#p ARGV
|
43
|
+
|
44
|
+
|
45
|
+
|
46
|
+
resolver = MacAddressEui48::OuiResolver.new()
|
47
|
+
options[:number].to_i.times do
|
48
|
+
if (options[:oui]==nil) then
|
49
|
+
if(options[:registered])then
|
50
|
+
mac = resolver.random_oui_mac
|
51
|
+
else
|
52
|
+
mac = resolver.random_mac
|
53
|
+
end
|
54
|
+
else
|
55
|
+
mac = resolver.random_mac_vendor(options[:oui])
|
56
|
+
end
|
57
|
+
puts mac
|
58
|
+
end
|
data/bin/oui_lookup.rb
ADDED
@@ -0,0 +1,30 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>
|
3
|
+
require 'mac_address_eui48.rb'
|
4
|
+
require 'optparse'
|
5
|
+
|
6
|
+
options = {}
|
7
|
+
optp = OptionParser.new do |opts|
|
8
|
+
opts.banner = "Usage: oui_lookup.rb [options] <mac_address>
|
9
|
+
Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>"
|
10
|
+
|
11
|
+
options[:help] = false
|
12
|
+
opts.on("-h", "--help", "Show this help") do
|
13
|
+
puts opts
|
14
|
+
exit
|
15
|
+
options[:help] = true
|
16
|
+
end
|
17
|
+
end.parse!
|
18
|
+
|
19
|
+
# Check required conditions
|
20
|
+
if ARGV.empty?
|
21
|
+
puts optp
|
22
|
+
exit(-1)
|
23
|
+
end
|
24
|
+
|
25
|
+
|
26
|
+
mac = ARGV.pop
|
27
|
+
resolver = MacAddressEui48::OuiResolver.new()
|
28
|
+
oui = resolver.oui_lookup(mac)
|
29
|
+
puts oui
|
30
|
+
|
data/lib/mac_address_eui48.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
|
2
|
-
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@
|
2
|
+
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>
|
3
3
|
|
4
4
|
require "mac_address_eui48/version"
|
5
5
|
require "mac_address_eui48/mac_address"
|
@@ -7,23 +7,21 @@ require "mac_address_eui48/oui_resolver"
|
|
7
7
|
|
8
8
|
|
9
9
|
module MacAddressEui48
|
10
|
-
OUI_FILE="data/oui.txt"
|
11
10
|
|
12
11
|
# MAC address format is hexadecimal characters separated by ':'
|
13
12
|
# ex: "AA:BB:CC:DD:EE:FF" or "11:22:33:44:55:66
|
14
|
-
|
15
13
|
def MacAddressEui48::is_valid_mac(mac_addr)
|
16
14
|
return (mac_addr =~ /^(\h\h:){5}\h\h$/)
|
17
15
|
end
|
18
16
|
|
19
|
-
def MacAddressEui48::
|
17
|
+
def MacAddressEui48::str_mac_to_int(a)
|
20
18
|
return a = a.delete(":").to_i(16)
|
21
19
|
end
|
22
20
|
|
23
|
-
def MacAddressEui48::
|
21
|
+
def MacAddressEui48::int_to_str_mac(i,sep=':')
|
24
22
|
a = i.to_s(16)
|
25
23
|
a = a.rjust(12,'0')
|
26
|
-
a = a.insert(10,
|
24
|
+
a = a.insert(10,sep).insert(8,sep).insert(6,sep).insert(4,sep).insert(2,sep)
|
27
25
|
return a.upcase
|
28
26
|
end
|
29
27
|
|
@@ -31,7 +29,9 @@ module MacAddressEui48
|
|
31
29
|
oui = ""
|
32
30
|
mac_array=mac_addr.upcase.split(":")
|
33
31
|
prefix = mac_array[0] + "-" + mac_array[1] + "-" + mac_array[2]
|
34
|
-
|
32
|
+
|
33
|
+
path = File.expand_path('../../data/oui.txt', __FILE__)
|
34
|
+
oui_file = File.open(path)
|
35
35
|
oui_file.each_line do |line|
|
36
36
|
if (line =~ /.*#{prefix}.*(hex)/) then
|
37
37
|
|
@@ -1,21 +1,22 @@
|
|
1
|
-
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@
|
1
|
+
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>
|
2
2
|
|
3
3
|
module MacAddressEui48
|
4
4
|
|
5
5
|
|
6
6
|
class MacAddress
|
7
7
|
include Comparable
|
8
|
-
|
9
|
-
|
8
|
+
|
10
9
|
def initialize(arg)
|
11
10
|
case arg
|
12
11
|
when MacAddress
|
13
|
-
@
|
12
|
+
@val = arg.to_i
|
14
13
|
when Integer
|
15
|
-
@
|
14
|
+
@val = arg
|
16
15
|
when String
|
16
|
+
# String value must be provided as hex char separated by ':'
|
17
17
|
if (MacAddressEui48::is_valid_mac(arg)) then
|
18
18
|
@mac_str=arg
|
19
|
+
@val=MacAddressEui48::str_mac_to_int(arg)
|
19
20
|
else
|
20
21
|
raise "Wrong format for string mac address #{arg}"
|
21
22
|
end
|
@@ -24,39 +25,43 @@ module MacAddressEui48
|
|
24
25
|
end
|
25
26
|
end
|
26
27
|
|
27
|
-
|
28
28
|
def to_i
|
29
|
-
|
29
|
+
@val
|
30
30
|
end
|
31
31
|
|
32
32
|
def <=>(other)
|
33
|
-
|
33
|
+
self.to_i <=> other.to_i
|
34
34
|
end
|
35
35
|
|
36
|
-
def to_s
|
37
|
-
@
|
36
|
+
def to_s(sep=':')
|
37
|
+
MacAddressEui48::int_to_str_mac(@val,sep).upcase
|
38
38
|
end
|
39
39
|
|
40
40
|
def is_broadcast
|
41
|
-
self.
|
41
|
+
#self.to_s == "FF:FF:FF:FF:FF:FF"
|
42
|
+
@val == 2**48-1
|
42
43
|
end
|
43
44
|
|
44
45
|
def is_unicast
|
45
|
-
|
46
|
+
!is_multicast
|
46
47
|
end
|
48
|
+
|
47
49
|
def is_multicast
|
48
|
-
|
50
|
+
mask = 1 << (5*8)
|
51
|
+
(mask & @val) !=0
|
49
52
|
end
|
53
|
+
|
50
54
|
def is_glob_uniq
|
51
|
-
|
55
|
+
!is_loc_admin
|
52
56
|
end
|
57
|
+
|
53
58
|
def is_loc_admin
|
54
|
-
|
59
|
+
mask = 2 << (5*8)
|
60
|
+
(mask & @val) !=0
|
55
61
|
end
|
56
|
-
|
57
62
|
|
58
63
|
def next
|
59
|
-
return MacAddress.new(
|
64
|
+
return MacAddress.new(((self.to_i) +1)%2**48)
|
60
65
|
end
|
61
66
|
alias_method :succ, :next
|
62
67
|
|
@@ -1,25 +1,37 @@
|
|
1
|
-
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@
|
1
|
+
# Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>
|
2
|
+
|
3
|
+
|
4
|
+
class Hash
|
5
|
+
def safe_invert
|
6
|
+
self.each_with_object( {} ) { |(key, value), out| ( out[value] ||= [] ) << key }
|
7
|
+
end
|
8
|
+
end
|
2
9
|
|
3
10
|
module MacAddressEui48
|
11
|
+
|
12
|
+
|
4
13
|
class OuiResolver
|
5
14
|
def initialize()
|
6
|
-
@
|
15
|
+
@oui_hash=Hash.new(nil)
|
16
|
+
path = File.expand_path('../../../data/oui.txt', __FILE__)
|
17
|
+
oui_file = File.open(path)
|
7
18
|
|
8
|
-
oui_file = File.open(OUI_FILE)
|
9
19
|
oui_file.each_line do |line|
|
10
20
|
if (line =~ /\(hex\)/) then
|
11
21
|
prefix = line.split("\t")[0].split(" ")[0].gsub("-",":").chomp
|
12
22
|
oui = line.split("\t")[2].chomp
|
13
|
-
@
|
14
|
-
end
|
15
|
-
|
23
|
+
@oui_hash[prefix]=oui
|
24
|
+
end
|
16
25
|
end
|
26
|
+
@reverse_oui_hash= @oui_hash.safe_invert
|
27
|
+
@vendor_table=@oui_hash.values
|
28
|
+
|
17
29
|
end
|
18
30
|
def oui_lookup(mac_addr)
|
19
|
-
return @
|
31
|
+
return @oui_hash[mac_addr[0..7].upcase]
|
20
32
|
end
|
21
33
|
def reverse_lookup(vendor)
|
22
|
-
return @
|
34
|
+
return @reverse_oui_hash[vendor]
|
23
35
|
end
|
24
36
|
def has_oui(mac)
|
25
37
|
return (oui_lookup(mac) != nil)
|
@@ -27,10 +39,13 @@ module MacAddressEui48
|
|
27
39
|
|
28
40
|
def random_mac
|
29
41
|
i = rand(2**48)
|
30
|
-
return MacAddressEui48::
|
42
|
+
return MacAddressEui48::int_to_str_mac(i)
|
31
43
|
end
|
32
44
|
def random_oui_mac
|
33
|
-
|
45
|
+
# Some vendors may appear more than once in the OUI table
|
46
|
+
# All vendors don't have the same probability to be picked
|
47
|
+
n = @vendor_table.size
|
48
|
+
vendor = @vendor_table[rand(n)]
|
34
49
|
return random_mac_vendor(vendor)
|
35
50
|
end
|
36
51
|
|
@@ -39,14 +54,13 @@ module MacAddressEui48
|
|
39
54
|
if (ouis.size <=0) then
|
40
55
|
raise "OUI not found #{vendor}"
|
41
56
|
end
|
57
|
+
|
42
58
|
oui = ouis[rand(ouis.size)]
|
43
|
-
i1 = MacAddressEui48::
|
59
|
+
i1 = MacAddressEui48::str_mac_to_int( oui + ":00:00:00")
|
44
60
|
i2 = rand(2**24)
|
45
61
|
i = i1 + i2
|
46
|
-
return MacAddressEui48::
|
47
|
-
end
|
48
|
-
|
62
|
+
return MacAddressEui48::int_to_str_mac(i)
|
63
|
+
end
|
49
64
|
end
|
50
|
-
|
51
|
-
|
65
|
+
|
52
66
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: mac_address_eui48
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-09-
|
12
|
+
date: 2015-09-08 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|
@@ -47,7 +47,10 @@ description:
|
|
47
47
|
email:
|
48
48
|
- mathieu.cunche@insa-lyon.fr
|
49
49
|
executables:
|
50
|
+
- benchmark.rb
|
50
51
|
- console
|
52
|
+
- gen_mac_address.rb
|
53
|
+
- oui_lookup.rb
|
51
54
|
- setup
|
52
55
|
extensions: []
|
53
56
|
extra_rdoc_files: []
|
@@ -56,7 +59,10 @@ files:
|
|
56
59
|
- LICENSE
|
57
60
|
- README.md
|
58
61
|
- Rakefile
|
62
|
+
- bin/benchmark.rb
|
59
63
|
- bin/console
|
64
|
+
- bin/gen_mac_address.rb
|
65
|
+
- bin/oui_lookup.rb
|
60
66
|
- bin/setup
|
61
67
|
- data/oui.txt
|
62
68
|
- lib/mac_address_eui48.rb
|