env/utils/scripts/ulagen.pl

62 lines
1.3 KiB
Perl

#!/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
# <http://creativecommons.org/publicdomain/zero/1.0/>.
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();