#!/usr/bin/perl # # usage: # # IPv6-DNS.pl -file < filename > # -domain < domain name > # -server < primary name server hostname > # -prefix < ipv6 prefix address > # # # IPv6-DNS.pl -- This perl script takes an IPv6 hosts file ( perhaps /etc/hosts ) # and creates the necessary DNS records ( AAAA and ptr ) # # -- Note: the file format must be consistent with that of /etc/hosts # # 2001:db8:baad::feed::1 myhostname # # -- The domain name may be specified on the command line # -- The primary name server's hostname # # Dependencies -- # # Net::IP -- http://www.cpan.org/modules/by-module/Net/Net-IP-1.25.tar.gz # Math::BigInt -- http://www.cpan.org/modules/by-module/Math/Math-BigInt-1.87.tar.gz # # created on Thursday, July 5, 2007 by Mark Leighty ( mleighty@harfordtechnology.com ) # # Copyright (2007) Harford Technology Corporation With the exception of commercial # resale, lease, license or other commercial transactions, permission is granted to # use, copy, modify, and distribute this software. By exercising this permission you # agree, that this Notice will accompany this software at all times. # # Harford Technology Corporation MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND # CONCERNING THIS SOFTWARE OR USE THEREOF. # #---------------------------- Revision Log ----------------------------------# $Version = 0.01; # mleighty@harfordtechnology.com # Currently "pre-production" however as features get added and we get some data # it should achieve basic functionality. $Version = 0.03; # mleighty@harfordtechnology.com # Resoloved issues with calculating the prefix name/number for file naming. Also # resolved many issues with comments in the source/hosts file. $Version = 0.04 # mleighty@harfordtechnology.com # Fixed a semantical error that prevented the db files from being constructed properly # when a prefix beyond a /32 was specified. #-------------------------- End Revision Log --------------------------------# # # Include the standard and specialized perl libraries # use Getopt::Long; # Processes command line arguments use Net::IP qw(:PROC); # Processes Address Operations ( v4/v6 ) # # Evaluate the command line arguments as gracefully as possible via the Getopt::Long library # sub Arguments { my $length = @ARGV; # Should be 3 with the supported Options if ( $length < 3 ) { &Usage; } } # End "sub Arguments" ----- # # Create a standard usage message. This will allow us to fail in a reasonably # graceful manner if the script is not invoked with the correct options. # sub Usage { my $definition = shift; print "\n"; print "\n"; print "Usage:\n"; print "\n"; print "IPv6-DNS.pl -file < filename > -domain < domainname> -server -prefix < domain ipv6 prefix address >"; print "\n"; print "\n"; print "\n"; print "Example:\n"; print "\n"; print "./IPv6-DNS.pl -file ./IPv6-hosts -domain ipv6-inc.com -server thunder -prefix ./2001:0db8::/32"; print "\n"; print "\n"; print "\n"; print "\n"; print "IPv6-DNS.pl .................................... http://www.harfordtechnology.com\n"; print "\n"; exit(0) # Punch out if we've reached this point } # End "sub Usage" ----- # # -- Begin Main Program Block # # ------------------------------------------------------------------------------------- # # &Arguments; # Check the command line arguments $result = &GetOptions ( "file=s", "domain=s", "server=s", "prefix=s" ); # utilize the Getoptions routine to process the command line # # Arrange varibles from GetOptions for easier manipulation # $file = $opt_file; $domain = $opt_domain; $server = $opt_server; $prefix = $opt_prefix; ( $prefix_number, $prefix_bits ) = split /::/, $prefix; # extract prefix number and bits for contextual operation ( $prefix_name = $prefix_number ) =~ s/:/-/g; # modify the prefix such that we can use it as a filename. $SOURCE_INFO = $file; $DB_DOMAIN = "./db.$domain"; $DB_PREFIX = "./db.$prefix_name"; $DB_LOCALHOST = "./db.v6localhost"; # # Process Source Information and normalize IP addresses # open SOURCE_INFO or die "can't open $file"; LINE: while ( $line = ) { next LINE if $line =~/^#|^\n/; # eliminate any comments or blank lines chop $line; # avoid last "\n' in field ( $address, $host ) = split(" ", $line); # split the logical record into address/host elements $address = ip_expand_address($address,6); # Expand IPv6 address to standard/full form $name{$address} .= $host; # Build array to contain information } close SOURCE_INFO; # close SOURCE_INFO as we now have everything dynamically # # handle special case of loopback address in IPv6 # # ------------------------------------------------------------------------------ # $v6_loopback = ip_expand_address("::1",6); # generate the standard/full form of the IPv6 loopback address # # Create the zone file for the localhost ( i.e.; ::1/128 ) # # This will generate the zone file for the localhost .... generally named # db.localhost or in this case db.v6localhost # # open (DB_LOCALHOST, ">$DB_LOCALHOST") or die "can't open $DB_LOCALHOST"; # open the filehandle for the db.v6loclhost file # # Print the necessary DNS directives to to the file as specified # print DB_LOCALHOST "; Zone file for 1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa ( Loopback Interface )\n"; print DB_LOCALHOST "\$TTL 3h\n"; print DB_LOCALHOST ip_reverse($v6_loopback)," IN SOA $server.$domain. hostmaster.$domain. (\n"; print DB_LOCALHOST "\t\t\t\t01\t\t; Serial Number -- Suggest format of YYMMddHHMM\n"; print DB_LOCALHOST "\t\t\t\t3h\t\t; Refresh after 3 hours\n"; print DB_LOCALHOST "\t\t\t\t1h\t\t; Retry after 1 hour\n"; print DB_LOCALHOST "\t\t\t\t1w\t\t; Expire after 1 week\n"; print DB_LOCALHOST "\t\t\t\t1h )\t\t; negative caching ttl of 1 hour\n"; print DB_LOCALHOST "\n"; print DB_LOCALHOST ";\n"; print DB_LOCALHOST "; Name Server Records ( NS )\n"; print DB_LOCALHOST ";\n"; print DB_LOCALHOST ip_reverse($v6_loopback),"\tIN NS\t$server.$domain.\n"; print DB_LOCALHOST "\n"; print DB_LOCALHOST ip_reverse($v6_loopback),"\tIN PTR\tlocalhost.\n"; print DB_LOCALHOST "\n"; close DB_LOCALHOST; # close db.v6localhost # # ------------------------------------------------------------------------------ # # # This section handles the forward lookup for the hosts specified # # ------------------------------------------------------------------------------ # # # Create the zone file for the domain ( i.e.; ipv6-inc.com ) # # This will generate the zone file for the domain .... generally named db.zone or in this case db.ipv6-inc.com # # open (DB_DOMAIN, ">$DB_DOMAIN") or die "can't open $DB_DOMAIN"; # open the filehandle for the db.domain file print DB_DOMAIN "; Zone file for $domain\n"; print DB_DOMAIN "\$TTL 3h\n"; print DB_DOMAIN "$domain. IN SOA $server.$domain. hostmaster.$domain. (\n"; print DB_DOMAIN "\t\t\t\t\t\t01\t\t; Serial Number -- Suggest format of YYMMddHHMM\n"; print DB_DOMAIN "\t\t\t\t\t\t3h\t\t; Refresh after 3 hours\n"; print DB_DOMAIN "\t\t\t\t\t\t1h\t\t; Retry after 1 hour\n"; print DB_DOMAIN "\t\t\t\t\t\t1w\t\t; Expire after 1 week\n"; print DB_DOMAIN "\t\t\t\t\t\t1h )\t\t; negative caching ttl of 1 hour\n"; print DB_DOMAIN "\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN "; Name Server Records ( NS )\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN "$domain.\t\t\t\t\tIN\tNS\t$server.$domain.\n"; print DB_DOMAIN "\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN "; Special Case for the loopback as always\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN "localhost.$domain.\t\t\t\tIN\tAAAA\t$v6_loopback\n"; print DB_DOMAIN "\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN "; IPv6 Address Records ( AAAA )\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN "\n"; foreach $address ( sort keys %name ) { $column = 47; # arbitrary value to better format the file/table $entry = $name{$address}.".".$domain."."; # needed for the array operation @test_array = split(//, $entry ); # place the variable into an array to ... $width = @test_array + 0; # get the string length print DB_DOMAIN "$name{$address}."."$domain."; while ( $width <= $column ) { print DB_DOMAIN " "; # pad the entry based on the column entry above $width++; } $address = ip_expand_address($address,6); print DB_DOMAIN "IN\tAAAA\t$address\n"; } print DB_DOMAIN "\n"; print DB_DOMAIN "\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN "; You may wish to add alias entries ( CNAME ) here\n"; print DB_DOMAIN ";\n"; print DB_DOMAIN ";somehost.$domain.\t\t\t\tIN\tCNAME\tsomeotherhost.$domain.\n"; print DB_DOMAIN "\n"; close DB_DOMAIN; # close db.$domain # # ------------------------------------------------------------------------------ # # # This section handles the reverse lookup for the hosts specified # # ------------------------------------------------------------------------------ # # # Create the zone file for the reverse lookup ( i.e.; 2001:db8) # # This will generate the zone file for ipv6.arpa .... generally named db.address or in this case db.2001-0db8 # # open (DB_PREFIX, ">$DB_PREFIX") or die "can't open $DB_PREFIX"; # open the filehandle for the db.domain file print DB_PREFIX "; Zone file for ", ip_reverse(ip_expand_address($prefix_number."::",6)),"\n"; print DB_PREFIX "\$TTL 3h\n"; print DB_PREFIX ip_reverse(ip_expand_address($prefix_number,6)),"\t IN SOA $server.$domain. hostmaster.$domain. (\n"; print DB_PREFIX "\t\t\t\t\t01\t\t; Serial Number -- Suggest format of YYMMddHHMM\n"; print DB_PREFIX "\t\t\t\t\t3h\t\t; Refresh after 3 hours\n"; print DB_PREFIX "\t\t\t\t\t1h\t\t; Retry after 1 hour\n"; print DB_PREFIX "\t\t\t\t\t1w\t\t; Expire after 1 week\n"; print DB_PREFIX "\t\t\t\t\t1h )\t\t; negative caching ttl of 1 hour\n"; print DB_PREFIX "\n"; print DB_PREFIX ";\n"; print DB_PREFIX "; Name Server Records ( NS )\n"; print DB_PREFIX ";\n"; print DB_PREFIX "\n"; print DB_PREFIX ip_reverse(ip_expand_address($prefix_number,6)),"\t\t\t\tIN\tNS\t$server.$domain.\n"; print DB_PREFIX "\n"; print DB_PREFIX ";\n"; print DB_PREFIX "; IPv6 Pointer Records ( PTR ) NOTE - ip6.arpa configuration\n"; print DB_PREFIX ";\n"; print DB_PREFIX "\n"; foreach $address ( sort keys %name ) { print DB_PREFIX ip_reverse($address), "\tIN\tPTR\t$name{$address}.$domain.\n"; } print DB_PREFIX "\n"; close DB_PREFIX; # close db.$domain # # ------------------------------------------------------------------------------ #