Skip to content

Instantly share code, notes, and snippets.

@mxmader
Last active April 4, 2017 20:28
Show Gist options
  • Save mxmader/bff12f29466b17cb9c559a47ded2ee5f to your computer and use it in GitHub Desktop.
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)
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