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 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