Skip to content

Instantly share code, notes, and snippets.

@wido
Created November 13, 2019 10:41
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wido/cf77a82813ea4d87b4f9b92a648ca040 to your computer and use it in GitHub Desktop.
Save wido/cf77a82813ea4d87b4f9b92a648ca040 to your computer and use it in GitHub Desktop.
Calculate RFC482 (SLAAC) IPv6 address a host will obtain
#!/usr/bin/env python3
#
# Calculate the IPv6 address a host will obtain per RFC4862
#
# Usage: ./ip6-eui64-address.py --prefix 2001:db8::/64 52:54:00:59:c2:b3
#
# Author: Wido den Hollander <wido@denhollander.io>
#
import argparse
import ipaddress
import re
def mac2eui64(mac, prefix=None):
'''
Convert a MAC address to a EUI64 address
or, with prefix provided, a full IPv6 address
'''
# http://tools.ietf.org/html/rfc4291#section-2.5.1
eui64 = re.sub(r'[.:-]', '', mac).lower()
eui64 = eui64[0:6] + 'fffe' + eui64[6:]
eui64 = hex(int(eui64[0:2], 16) ^ 2)[2:].zfill(2) + eui64[2:]
if prefix is None:
return ':'.join(re.findall(r'.{4}', eui64))
else:
try:
net = ipaddress.ip_network(prefix, strict=False)
euil = int('0x{0}'.format(eui64), 16)
return str(net[euil])
except: # pylint: disable=bare-except
return
if __name__ == '__main__':
parser = argparse.ArgumentParser(description='Calculate IPv6 address based on Prefix and MAC')
parser.add_argument('mac', help='MAC address to be used')
parser.add_argument('--prefix', help='IPv6 prefix', default='fe80::/10')
args = parser.parse_args()
prefix = ipaddress.ip_network(args.prefix)
if prefix.version != 6:
raise ValueError('Prefix should be IP version 6')
if prefix.prefixlen > 64:
raise ValueError('Prefix should be at least 64-bits in size')
address = ipaddress.ip_address(mac2eui64(mac=args.mac, prefix=str(prefix)))
print(address)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment