#!/usr/bin/perl -w # wide_area_publish_address, v 0.2 # Copyright (C) 2009 Federico Lucifredi # This program is free software; you can redistribute it and/or # modify it under the terms of the GNU General Public License, version 2 # as published by the Free Software Foundation. # # This program is distributed in the hope that it will be useful, # but WITHOUT ANY WARRANTY; without even the implied warranty of # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # GNU General Public License for more details. # # You should have received a copy of the GNU General Public License # along with this program; if not, write to the Free Software Foundation, Inc., # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # FIXME optionally detect external address if NAT'd ? # FIXME add socket timeout when remote server down ? use strict; use Net::DNS; use IO::Interface::Simple; use File::Basename; # Variables to configure the script's operation my $hostname = 'ooga'; # Device hostname my $domain = 'dynamic.booga.org.'; # Domain name my $nameserver = 'ns1.booga.org'; # Primary nameserver for your zone my $keyname = 'md5key'; # Name of the key my $key = 'se64bAsE64BASE64BasE64=='; # The HMAC-MD5 TSIG key my $interface = 'eth0'; # Interface whose IP is to be published # Create the update packet for clean-up my $update = Net::DNS::Update->new($domain); # Delete all records for given name $update->push(pre => yxdomain("$hostname.$domain")); $update->push(update => rr_del("$hostname.$domain")); # Sign the update $update->sign_tsig($keyname, $key); # Send the update to the zone's primary master. my $res = Net::DNS::Resolver->new; $res->nameservers($nameserver); my $reply = $res->send($update); # When program invoked with this name, terminate operation at this point if (basename($0) eq "wide_area_delete") { print "Deleting records for host $hostname\n"; process_retcode($reply); exit(0); } # my $address = '164.99.130.75'; my $if = IO::Interface::Simple->new($interface); unless (defined($if->address)) { print "Interface $interface does not currently have an address\n"; exit(1); } my $address = $if->address; print "Publishing address $address to $nameserver\n"; # Create the update packet. $update = Net::DNS::Update->new($domain); # Add A record for the name $update->push(update => rr_add("$hostname.$domain 1 A $address")); # Sign the update $update->sign_tsig($keyname, $key); # Send the update to the zone's primary master. $res = Net::DNS::Resolver->new; $res->nameservers($nameserver); $reply = $res->send($update); # Inform user of the result process_retcode($reply); # Examines the result of the DNS operation and exits sub process_retcode { my ($reply) = @_; if ($reply) { if ($reply->header->rcode eq 'NOERROR') { print "Update succeeded\n"; exit(0); } else { print 'Update failed: ', $reply->header->rcode, "\n"; exit(2); } } else { print 'Update failed: ', $res->errorstring, "\n"; exit(3); } }