Skip to content

Instantly share code, notes, and snippets.

@sir-ragna
Created July 2, 2018 21:15
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save sir-ragna/1334b888ca9bfadc8c7f826e87b3c086 to your computer and use it in GitHub Desktop.
Save sir-ragna/1334b888ca9bfadc8c7f826e87b3c086 to your computer and use it in GitHub Desktop.
IPv6 script to generate ULA addresses
#!/usr/bin/python3
"""
Generate a list of IPv6 ALU(Unique Local Addresses).
"""
from ipaddress import IPv6Address
from random import sample
from os import urandom
amount = 100 # amount to generate
def b2a(some_bytes):
"""Bytes to ascii"""
return "".join(["{:02x}".format(c) for c in some_bytes])
# IPv6 Unique Local Address(ULA) format RFC 4193
# 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
# xx yy : yy yy : yy yy : zz zz : hh hh : hh hh : hh hh : hh hh
# x => ULA prefix
# y => ROUTING prefix
# z => NETWORK
# h => HOST BITS
#
# https://www.rfc-editor.org/rfc/rfc4193.txt
#+--------+-+------------+-----------+----------------------------+
#| 7 bits |1| 40 bits | 16 bits | 64 bits |
#+--------+-+------------+-----------+----------------------------+
#| Prefix |L| Global ID | Subnet ID | Interface ID |
#+--------+-+------------+-----------+----------------------------+
PREFIX = 0xFC # FC00::/7 prefix to identify Local IPv6 unicast addresses
L = 0x1 # L is set to 1 if the prefix is locally assigned.
# (0 may be defined in the future)
FIRST_BYTE = bytes([PREFIX | L]) # 0xFD # | 7 bits |1|
GLOBAL_ID = b'\x00\x00\x00\x00\x00' # | 40 bits |
SUBNET_ID = b'\x00\x00' # | 16 bits |
INTERFACE_ID = b'\x00\x00\x00\x00\x00\x00\x00\x00' # | 64 bits |
CIDR_SUFFIX = 128 - (len(INTERFACE_ID) * 8)
# Generate the Global ID and the Subnet ID.
GLOBAL_ID = urandom(5)
SUBNET_ID = urandom(2)
print('\nGenerating {amount} IPs'.format(amount=amount))
address_set = set()
for i in range(amount):
INTERFACE_ID = urandom(len(INTERFACE_ID))
ipaddr = IPv6Address(FIRST_BYTE + GLOBAL_ID + SUBNET_ID + INTERFACE_ID)
address_set.add(ipaddr)
print('Here\'s a sample of 5 addresses.')
for a in sample(address_set, 5):
print(f" {a}")
out_file = 'ipv6-{}-{}.txt'.format(b2a(GLOBAL_ID), b2a(SUBNET_ID))
with open(out_file, 'w') as fh:
fh.write('# Network(CIDR): {IPv6Address}/{CIDR_SUFFIX}\n'.format(
IPv6Address=(IPv6Address(FIRST_BYTE +
GLOBAL_ID +
SUBNET_ID +
INTERFACE_ID)),
CIDR_SUFFIX=CIDR_SUFFIX))
fh.write("# Network hex: {}\n".format(b2a(FIRST_BYTE + GLOBAL_ID + SUBNET_ID)))
fh.write("# ULA Prefix: {:02x}\n".format(ord(FIRST_BYTE)))
fh.write("# Global ID: {}\n".format(b2a(GLOBAL_ID)))
fh.write("# Subnet ID: {}\n\n".format(b2a(SUBNET_ID)))
for a in list(address_set):
fh.write(f"{a}\n")
print(f'\n{len(address_set)} addresses written to {out_file}')
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment