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 CHANGED
@@ -1,36 +1,85 @@
1
1
  # MacAddressEui48
2
2
 
3
- Welcome to your new gem! In this directory, you'll find the files you need to be able to package up your Ruby library into a gem. Put your Ruby code in the file `lib/mac_address_eui48`. To experiment with that code, run `bin/console` for an interactive prompt.
4
-
5
- TODO: Delete this and the text above, and describe your gem
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
- Add this line to your application's Gemfile:
10
-
11
- ```ruby
12
- gem 'mac_address_eui48'
37
+ ```bash
38
+ gem install mac_address_eui48
13
39
  ```
14
40
 
15
- And then execute:
16
-
17
- $ bundle
41
+ ## Usage
18
42
 
19
- Or install it yourself as:
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
- $ gem install mac_address_eui48
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
- ## Usage
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/[USERNAME]/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.
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
 
@@ -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
@@ -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
+
@@ -1,5 +1,5 @@
1
1
 
2
- # Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@innsa-lyon.fr>
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::macaddr_to_int(a)
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::int_to_macaddr(i)
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,':').insert(8,':').insert(6,':').insert(4,':').insert(2,':')
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
- oui_file = File.open(OUI_FILE)
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@innsa-lyon.fr>
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
- attr_reader :mac_str
9
-
8
+
10
9
  def initialize(arg)
11
10
  case arg
12
11
  when MacAddress
13
- @mac_str = arg.to_s
12
+ @val = arg.to_i
14
13
  when Integer
15
- @mac_str = MacAddressEui48::int_to_macaddr(arg)
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
- return MacAddressEui48::macaddr_to_int(@mac_str)
29
+ @val
30
30
  end
31
31
 
32
32
  def <=>(other)
33
- MacAddressEui48::macaddr_to_int(self.mac_str) <=> MacAddressEui48::macaddr_to_int(other.mac_str)
33
+ self.to_i <=> other.to_i
34
34
  end
35
35
 
36
- def to_s
37
- @mac_str
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.mac_str == "FF:FF:FF:FF:FF:FF"
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
- return !is_multicast
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
- return !is_loc_admin
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(MacAddressEui48::int_to_macaddr(((self.to_i) +1)%2**48))
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@innsa-lyon.fr>
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
- @hash=Hash.new(nil)
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
- @hash[prefix]=oui
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 @hash[mac_addr[0..7].upcase]
31
+ return @oui_hash[mac_addr[0..7].upcase]
20
32
  end
21
33
  def reverse_lookup(vendor)
22
- return @hash.select { |key, val| val == vendor }.keys
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::int_to_macaddr(i).upcase
42
+ return MacAddressEui48::int_to_str_mac(i)
31
43
  end
32
44
  def random_oui_mac
33
- vendor = @hash.values.uniq[rand(@hash.values.uniq.size)]
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::macaddr_to_int( oui + ":00:00:00")
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::int_to_macaddr(i)
47
- end
48
-
62
+ return MacAddressEui48::int_to_str_mac(i)
63
+ end
49
64
  end
50
-
51
-
65
+
52
66
  end
@@ -1,5 +1,5 @@
1
- # Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@innsa-lyon.fr>
1
+ # Copyright (C) 2015 Mathieu Cunche <mathieu.cunche@insa-lyon.fr>
2
2
 
3
3
  module MacAddressEui48
4
- VERSION = "0.1.0"
4
+ VERSION = "0.1.1"
5
5
  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.0
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-07 00:00:00.000000000 Z
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