[avahi] wide area publishing - tinkering

Federico Lucifredi flucifredi at acm.org
Fri Jan 2 18:38:32 PST 2009


Hello Guys,
 I have come down with a bug (of the non-digital kind), which is rather
unusual for me. Needless to say, it torpedoed my plan to clean up the
patches last week and slipped that to next week, but since I am bored to
 tears in bed and my headache decided to let up a bit this afternoon, I
thought I would do some prep-work.

 OS-X 10.4, which was my test platform for writing the patch, was
restored to one of my machines (something appears to be broken or
undocumented in 10.5, and I am tired of hitting my head against it and
wasting my time).

 The other thing I wanted was a way to send test update packets easily,
so I whipped out a bit of Perl. While I was doing this, I realized there
may be some (little) use to this script in daemon-less scenarios: for
instance, the WD Mybook can be hacked into a pretty cheap Linux NAS but
it uses daemon-less mDNS only, which leaves the wide area option out.

 With this script, one could set out to publish the IP of a chosen
interface at bootup, and voila', your DHCP-booted NAS has an FQDN.

 So, the Avahi patches will start coming in for revision next week. But
in the meantime, here is something to critique, poke at, and comment on
if you feel like it :-)

 Best -F

------------8<------------------------------------------------------
#!/usr/bin/perl -w

# wide_area_publish_address, v 0.1
# 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_address") {
    print "Deleting records for host $hostname\n";
    process_retcode($reply);
    exit(0);
}

# my $address = '192.168.1.100';
my $if = IO::Interface::Simple->new($interface);
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(1);
    }
} else {
    print 'Update failed: ', $res->errorstring, "\n";
    exit(2);
}
}

------------8<------------------------------------------------------

-- 
_________________________________________
-- "'Problem' is a bleak word for challenge" - Richard Fish
(Federico L. Lucifredi) - flucifredi at acm.org - GnuPG 0x4A73884C


More information about the avahi mailing list