#!/usr/bin/perl -w # # Extract zones and their nameservers from tinydns-data file(s) and # send DNS "NOTIFY" requests to nameservers listed in notify-list # The file "notify-list" must contain one nameserver per line # # Written 2001-02-20 by Andrew Pam # Modified 2002-08-22 to support records that define nameserver addresses # Modified 2002-08-30 to support "." records as well as "&" records # Copyright (c) 2001-02 Serious Cybernetics # Partially inspired by dnsnotify by Jos Backus and James Raftery # Distribute and modify freely, providing attribution is preserved use Socket; use Net::DNS; my @self = split /\//, $0; die "Usage: $self[-1] zonefile [...]\n" unless $#ARGV >= 0; my %notify; open(LIST, "notify-list") or die "Can't open notify-list file\n"; while () { ($_) = split; my $server = inet_aton $_ or (warn "$_ is not a valid server", next); $notify{$server} = ""; } close(LIST); while (<>) { chomp; my ($zone, $ip, $server) = /^[\&\.]([^:]*):([^:]*):([^:]*)/ or next; $server = inet_aton ($ip || $server) or next; $notify{$server} .= "$zone " if defined $notify{$server}; } my $res = new Net::DNS::Resolver; foreach $s (keys %notify) { next unless $_ = $notify{$s}; foreach (my @zone = split) { my $packet = new Net::DNS::Packet($_, "SOA", "IN"); die unless defined $packet; ($packet->header)->opcode("NS_NOTIFY_OP"); ($packet->header)->rd(0); ($packet->header)->aa(1); my $server = inet_ntoa($s); $res->nameservers($server); $reply = $res->send($packet); if (defined $reply) { print "Received NOTIFY answer for $_ from " . $reply->answerfrom . "\n"; } else { warn "\$res->send indicates NOTIFY error for $server\n"; } } }