#!/usr/bin/env perl # env # Written in 2021 by Lucas # CC0 1.0 Universal/Public domain - No rights reserved # # To the extent possible under law, the author(s) have dedicated all # copyright and related and neighboring rights to this software to the # public domain worldwide. This software is distributed without any # warranty. You should have received a copy of the CC0 Public Domain # Dedication along with this software. If not, see # . use v5.14; use strict; use warnings; use Digest::SHA qw(sha1_hex); use Time::HiRes qw(gettimeofday); use constant { UNIX_NTP_EPOCH_OFFSET => 2208988800, }; my $__progname = ($0 =~ s,^.*/,,r); sub usage { say STDERR "usage: $__progname MAC"; exit 1; } sub err { say STDERR "$__progname: @_"; exit 1; } sub main { usage if @ARGV != 1; my $mac = shift @ARGV; my @bytes = split(/[-:]/, $mac); err "$mac: invalid MAC address" if @bytes != 6 || grep {!m/^[0-9a-fA-F]{1,2}$/} @bytes; my @eui64 = map {hex} (@bytes[0..2], "ff", "fe", @bytes[3..5]); $eui64[0] ^= 0x02; my ($sec, $usec) = gettimeofday(); $sec = ($sec + UNIX_NTP_EPOCH_OFFSET) & 0xffffffff; $usec = int(($usec / 1e6) * 0xffffffff); my $gid = substr(sha1_hex(pack("N2C8", $sec, $usec, @eui64)), 30, 10); my $ula_prefix = join(":", "fd$gid" =~ m/.{4}/g); say "${ula_prefix}::/48"; } main();