Skip to content

Instantly share code, notes, and snippets.

@dlundquist
Created July 25, 2010 06:20
Show Gist options
  • Save dlundquist/489357 to your computer and use it in GitHub Desktop.
Save dlundquist/489357 to your computer and use it in GitHub Desktop.
#!/usr/bin/perl
# Generates a random IPv6 address in the same subnet as the machine is currently in
# Written by Dustin Lundquist <dustin@null-ptr.net>
use strict;
use warnings;
sub getglobaladdress {
open (IP, '-|', '/sbin/ip address show')
or return undef;
while (my $line = <IP>) {
# inet6 2607:f700:1:a0:230:48ff:fe57:b20e/64 scope global
if ($line =~ m/^\s+inet6 ((?:[0-9a-f]{0,4}\:)+[0-9a-f]{0,4})\/(\d+) scope global/) {
close (IP);
return ($1, $2);
}
}
close (IP);
return undef;
}
sub getprefix {
my ($addr, $bits)= getglobaladdress
or return undef;
my $remaining_bits = $bits;
my $prefix = '';
while ($remaining_bits > 0) {
if ($remaining_bits >= 16 and $addr =~ /^([0-9a-f]{1,3}\:)[0-9a-f]/) {
$remaining_bits -= 16;
$prefix .= $1;
$addr =~ s/^$1//;
next;
} elsif ($remaining_bits >= 16 and $addr =~ /^([0-9a-f]{1,3}\:)((?:\:[0-9a-f]{1,3})+)/) {
# :: in the prefix protion of the address
$remaining_bits -= 16;
$prefix .= $1;
my $rest = $2;
die ":: in network portion of address not supported at this point\n";
}
die "prefixes which are not multiples of 16 not supported";
}
return($prefix, $bits);
}
my ($address, $bits) = getprefix
or die ("Unable to fetch a public prefix\n");
while ($bits < 128) {
if ($bits + 16 < 128) {
$address .= sprintf("%x", rand(65533) + 1) . ':'; # Avoid all 0's and all 1's addresses
$bits += 16;
next;
}
if ($bits + 16 == 128) {
$address .= sprintf("%x", rand(65533) + 1);
$bits += 16;
next;
}
die "prefixes which are not multiples of 16 not supported ($address $bits)";
}
print "$address\n";
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment