diff --git a/CHANGELOG.md b/CHANGELOG.md index ee87ac18..e39ac5fd 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,11 @@ # Changelog +## 0.11.1 (1/15/2015) + +### New features +* [#116](https://github.com/trema/pio/issues/116): Support Cisco-style MAC addresses. + + ## 0.11.0 (1/15/2015) ### New features diff --git a/lib/pio/mac.rb b/lib/pio/mac.rb index dea69895..f5f487a5 100644 --- a/lib/pio/mac.rb +++ b/lib/pio/mac.rb @@ -32,7 +32,7 @@ def initialize(value) fail TypeError end rescue ArgumentError, TypeError - raise InvalidValueError, "Invalid MAC address: #{ value.inspect }" + raise InvalidValueError, "Invalid MAC address: #{value.inspect}" end # @!group Converters @@ -113,7 +113,7 @@ def multicast? # Mac.new("ff:ff:ff:ff:ff:ff").broadcast? #=> true # def broadcast? - to_a.all? { | each | each == 0xff } + to_a.all? { |each| each == 0xff } end # @@ -196,9 +196,11 @@ def inspect private def parse_mac_string(mac) - octet_regex = '[0-9a-fA-F][0-9a-fA-F]' - if /^(#{ octet_regex }:){5}(#{ octet_regex })$/ =~ mac - mac.gsub(':', '').hex + octet = '[0-9a-fA-F][0-9a-fA-F]' + doctet = octet * 2 + case mac + when /^(?:#{octet}(:)){5}#{octet}$/, /^(?:#{doctet}(\.)){2}#{doctet}$/ + mac.gsub(Regexp.last_match[1], '').hex else fail ArgumentError end diff --git a/lib/pio/type/mac_address.rb b/lib/pio/type/mac_address.rb index 25dbe77f..d11b478a 100644 --- a/lib/pio/type/mac_address.rb +++ b/lib/pio/type/mac_address.rb @@ -8,14 +8,7 @@ class MacAddress < BinData::Primitive array :octets, type: :uint8, initial_length: 6 def set(value) - case value - when String - self.octets = value.split(':').map { |each| ('0x' + each).hex } - when Integer - self.octets = (0..5).map { |each| value >> ((5 - each) * 8) & 0xff } - else - self.octets = value.to_a - end + self.octets = Mac.new(value).to_a end def get diff --git a/spec/pio/mac_spec.rb b/spec/pio/mac_spec.rb index dee3c978..83a03cfc 100644 --- a/spec/pio/mac_spec.rb +++ b/spec/pio/mac_spec.rb @@ -46,6 +46,81 @@ subject { super().to_s } it { is_expected.to eq '11:22:33:44:55:66' } end + + describe '#to_str' do + context 'when "MAC = " + subject' do + it { expect('MAC = ' + subject).to eq 'MAC = 11:22:33:44:55:66' } + end + end + + describe '#multicast?' do + subject { super().multicast? } + it { is_expected.to be_truthy } + end + + describe '#broadcast?' do + subject { super().broadcast? } + it { is_expected.to be_falsey } + end + + describe '#reserved?' do + subject { super().reserved? } + it { is_expected.to be_falsey } + end + end + + context 'with "1122.3344.5566" (Cisco style)' do + let(:value) { '1122.3344.5566' } + + describe '#==' do + it { is_expected.to eq Pio::Mac.new('1122.3344.5566') } + it { is_expected.to eq Pio::Mac.new('11:22:33:44:55:66') } + it { is_expected.to eq '1122.3344.5566' } + it { is_expected.to eq '11:22:33:44:55:66' } + it { is_expected.not_to eq Pio::Mac.new('6655.4433.2211') } + it { is_expected.not_to eq Pio::Mac.new('66:55:44:33:22:11') } + it { is_expected.not_to eq '6655.4433.2211' } + it { is_expected.not_to eq '66:55:44:33:22:11' } + it { is_expected.to eq 0x112233445566 } + it { is_expected.not_to eq 42 } + it { is_expected.not_to eq 'INVALID_MAC_ADDRESS' } + end + + describe '#eql?' do + it { expect(subject).to eql Pio::Mac.new('1122.3344.5566') } + it { expect(subject).to eql Pio::Mac.new('11:22:33:44:55:66') } + it { expect(subject).to eql '1122.3344.5566' } + it { expect(subject).to eql '11:22:33:44:55:66' } + it { expect(subject).not_to eql Pio::Mac.new('6655.4433.2211') } + it { expect(subject).not_to eql Pio::Mac.new('66:55:44:33:22:11') } + it { expect(subject).not_to eql '6655.4433.2211' } + it { expect(subject).not_to eql '66:55:44:33:22:11' } + it { expect(subject).to eql 0x112233445566 } + it { expect(subject).not_to eql 42 } + it { expect(subject).not_to eql 'INVALID_MAC_ADDRESS' } + end + + describe '#hash' do + subject { super().hash } + it { is_expected.to eq Pio::Mac.new('1122.3344.5566').hash } + it { is_expected.to eq Pio::Mac.new('11:22:33:44:55:66').hash } + end + + describe '#to_i' do + subject { super().to_i } + it { is_expected.to eq 0x112233445566 } + end + + describe '#to_a' do + subject { super().to_a } + it { is_expected.to eq [0x11, 0x22, 0x33, 0x44, 0x55, 0x66] } + end + + describe '#to_s' do + subject { super().to_s } + it { is_expected.to eq '11:22:33:44:55:66' } + end + describe '#to_str' do context 'when "MAC = " + subject' do it { expect('MAC = ' + subject).to eq 'MAC = 11:22:33:44:55:66' }