Last active
April 4, 2017 20:28
-
-
Save mxmader/bff12f29466b17cb9c559a47ded2ee5f to your computer and use it in GitHub Desktop.
analyzing mac addresses rejected by foreman v1.14's new validation logic (excluding non-unicast MAC addresses)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
require 'ipaddr' | |
require 'socket' | |
IP_REGEXP ||= /\A((25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)(\.|$)){4}\z/ | |
MAC_REGEXP ||= /\A([a-f0-9]{1,2}:){5}[a-f0-9]{1,2}\z/i | |
MAC_REGEXP_64BIT ||= /\A([a-f0-9]{1,2}:){19}[a-f0-9]{1,2}\z/i | |
HOST_REGEXP ||= /\A(([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\.)*([a-z0-9]|[a-z0-9][a-z0-9\-]*[a-z0-9])\z/ | |
MASK_REGEXP ||= /\A((255.){3}(0|128|192|224|240|248|252|254))|((255.){2}(0|128|192|224|240|248|252|254).0)|(255.(0|128|192|224|240|248|252|254)(.0){2})|((128|192|224|240|248|252|254)(.0){3})\z/ | |
def validate_mac(mac) | |
return false if mac.nil? | |
case mac.size | |
when 17 | |
return true if (mac =~ MAC_REGEXP) | |
when 59 | |
return true if (mac =~ MAC_REGEXP_64BIT) | |
end | |
false | |
end | |
def multicast_mac?(mac) | |
return false unless validate_mac(mac) | |
# Get the first byte | |
msb = mac.tr('.:-', '').slice(0..1).to_i(16) | |
# Is least significant bit set? | |
msb & 0b1 == 1 | |
end | |
def broadcast_mac?(mac) | |
return false unless validate_mac(mac) | |
mac.downcase == 'ff:ff:ff:ff:ff:ff' | |
end | |
# validates the mac and raises an error | |
def validate_mac!(mac) | |
raise Error, "Invalid MAC #{mac}" unless validate_mac(mac) | |
mac | |
end | |
test_macs = [ | |
'aa:bb:cc:dd:ee:ff', | |
'00:bb:cc:dd:ee:ff', | |
'b7:35:bc:ba:71:e8', | |
'39:52:a6:55:ea:80', | |
'40:52:a6:55:ea:80', | |
'41:52:a6:55:ea:80', | |
'4a:52:a6:55:ea:80', | |
'4b:52:a6:55:ea:80', | |
'4d:52:a6:55:ea:80', | |
'4f:52:a6:55:ea:80', | |
] | |
for test in test_macs | |
test_slice = test.tr('.:-', '').slice(0..1) | |
test_int = test_slice.to_i(16) | |
puts "[" + test + "]" | |
puts test_slice | |
puts test_int | |
puts "valid: " + validate_mac(test).to_s | |
puts "broadcast: " + broadcast_mac?(test).to_s | |
puts "multicast: " + multicast_mac?(test).to_s | |
puts '' | |
end | |
puts "it turns out i was auto-generating MAC addresses without any regard for their binary structure" | |
puts "and often generating MACs with an odd 2nd hex digit of the first octet, thus making the least" | |
puts "significant bit equal to 1 and pissing off foreman's validator." | |
puts "" | |
puts "womp, womp womp...." | |
puts "" |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment