mac_address_eui48 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|