]> mj.ucw.cz Git - nsc-5.git/blob - bin/convert
Yet another fix of blackhole zones
[nsc-5.git] / bin / convert
1 #!/usr/bin/perl -w
2 #
3 #       Convert -- A Tool for Conversion of Zone Files to NSC Format
4 #
5 #       (c) 1999--2003 Martin Mares <mj@ucw.cz>
6 #
7
8 use Getopt::Std;
9 use Net::DNS::Resolver;
10
11 getopts('v', \%opts) && @ARGV == 2 || do {
12         print "Usage: convert [-v] <domain> <server>\n";
13         exit 1;
14 };
15 $domain = norm_name($ARGV[0]);
16
17 $verbose = $opts{"v"};
18
19 $res = new Net::DNS::Resolver;
20 $res->nameservers($ARGV[1]);
21 $res->defnames(0);
22 $res->dnsrch(0);
23 $res->debug(0);
24
25 $verbose && print "; Fetching zone data for $domain\n";
26 @zone = $res->axfr($domain) or die("Zone transfer failed");
27 foreach $r (@zone) {
28         if ($verbose) {
29                 $name = $r->string;
30                 print "; $name\n";
31         }
32         $type = $r->type;
33         $n = fix($r->name);
34         if ($type eq "A") {
35                 $have{$n} = 1;
36                 $ips{$n} = (defined $ips{$n} ? $ips{$n} : "") . ", " . $r->address;
37         } elsif ($type eq "SOA") {
38                 print "SOA($domain)\n";
39         } elsif ($type eq "MX") {
40                 $have{$n} = 1;
41                 $mx{$n} = ((defined $mx{$n}) ? $mx{$n} . ", " : "") . $r->preference . " " . fix($r->exchange);
42         } elsif ($type eq "CNAME") {
43                 $cn = fix($r->cname);
44                 $have{$cn} = 1;
45                 $cn{$cn} = ((defined $cn{$cn}) ? $cn{$cn} . ", " : "") . $n;
46         } elsif ($type eq "NS") {
47                 if ($n ne "@") {
48                         $sub{$n} = 1;
49                         $subd{$n} .= "NS(" . fix($r->nsdname) . ")\n";
50                 }
51         } else {
52                 print "; FIXME: ", $r->string, "\n";
53         }
54 }
55 go("@", 0);
56 delete $have{"@"};
57 foreach $n (sort keys %have) {
58         go($n, 1);
59 }
60 foreach $n (sort keys %sub) {
61         print "\nD($n)\n";
62         print $subd{$n};
63 }
64
65 exit 0;
66
67 sub go {
68         my $n = shift @_;
69         my $flag = shift @_;
70
71         if (defined $ips{$n}) { print "H($n$ips{$n})\n"; }
72         elsif ($flag) { print "H($n)\n"; }
73         if (defined $mx{$n}) { print "MX($mx{$n})\n"; }
74         if (defined $cn{$n}) { print "ALIAS($cn{$n})\n"; }
75 }
76
77 sub norm_name {
78         my $n = shift @_;
79         $n =~ s/\.$//;
80         $n =~ tr[A-Z][a-z];
81         return $n;
82 }
83
84 sub fix {
85         my $n = shift @_;
86         if ($n eq $domain) { return "@"; }
87         elsif ($n =~ /^(.*)\.$domain$/) { return $1; }
88         else { return "$n."; }
89 }