#!/usr/bin/perl ## Copyright (c) 1996, 1997 by Internet Software Consortium ## ## Permission to use, copy, modify, and distribute this software for any ## purpose with or without fee is hereby granted, provided that the above ## copyright notice and this permission notice appear in all copies. ## ## THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS ## ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES ## OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE ## CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL ## DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR ## PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ## ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS ## SOFTWARE. ## $Id: named-bootconf.pl,v 8.15 1997/06/09 17:46:52 halley Exp $ # This is a filter. Input is a named.boot. Output is a named.conf. # (named.boot was the old-style configuration file used with BIND-4. If # you already have such a file for your site, you can run it through this # script to convert it to the named.conf config file used by BIND-8) $new_config = ""; $have_options = 0; %options = (); %options_comments = (); @topology = (); @topology_comments = (); @bogus = (); @bogus_comments = (); @transfer_acl = (); @transfer_comments = (); $logging = ""; while(<>) { next if /^$/; # skip comment-only lines if (/^\s*;+\s*(.*)$/) { $new_config .= "// $1\n"; next; } # handle continued lines while (/\\$/) { s/\\$/ /; $_ .= <>; } chop; # deal with lines ending in a coment if (s/\s*;+\s*(.*)$//) { $comment = "// $1"; } else { $comment = ""; } ($directive, @rest) = split; $class = ""; if ($directive =~ /^(.*)\/(.*)$/) { $directive = $1; $class = $2; } if ($directive eq "primary") { $zname = shift(@rest); &maybe_print_comment("","\n"); $new_config .= "zone \"$zname\" "; if ($class ne "") { $new_config .= "$class "; } $new_config .= "{\n"; $new_config .= "\ttype master;\n"; $filename = shift(@rest); $new_config .= "\tfile \"$filename\";\n"; $new_config .= "};\n\n"; } elsif ($directive eq "secondary" || $directive eq "stub") { if ($directive eq "secondary") { $type = "slave"; } else { $type = "stub"; } $zname = shift(@rest); &maybe_print_comment("","\n"); $new_config .= "zone \"$zname\" "; if ($class ne "") { $new_config .= "$class "; } $new_config .= "{\n"; $new_config .= "\ttype $type;\n"; $filename = pop(@rest); $new_config .= "\tfile \"$filename\";\n"; $new_config .= "\tmasters {\n"; foreach $master (@rest) { $new_config .= "\t\t$master;\n"; } $new_config .= "\t};\n"; $new_config .= "};\n\n"; } elsif ($directive eq "cache") { $zname = shift(@rest); &maybe_print_comment("","\n"); $new_config .= "zone \"$zname\" {\n"; $new_config .= "\ttype hint;\n"; $filename = shift(@rest); $new_config .= "\tfile \"$filename\";\n"; $new_config .= "};\n\n"; } elsif ($directive eq "directory") { $options{"directory"} = "\"$rest[0]\""; $options_comments{"directory"} = $comment; $have_options = 1; } elsif ($directive eq "check-names") { $type = shift(@rest); if ($type eq "primary") { $type = "master"; } elsif ($type eq "secondary") { $type = "slave"; } $action = shift(@rest); $options{"check-names $type"} = $action; $options_comments{"check-names $type"} = $comment; $have_options = 1; } elsif ($directive eq "forwarders") { $options{"forwarders"}="{\n"; foreach $forwarder (@rest) { $options{"forwarders"} .= "\t\t$forwarder;\n"; } $options{"forwarders"} .= "\t}"; $options_comments{"forwarders"} = $comment; $have_options = 1; } elsif ($directive eq "slave") { &handle_options("forward-only"); } elsif ($directive eq "options") { &handle_options(@rest); } elsif ($directive eq "limit") { &handle_limit(@rest); } elsif ($directive eq "include") { $new_config .= "// make sure your include is still in the right place\n"; $comment = "\t" . $comment; $new_config .= "include \"$rest[0]\";$comment\n\n"; } elsif ($directive eq "xfrnets" || $directive eq "tcplist") { if ($comment ne "") { $comment = "\t$comment"; } foreach $elt (@rest) { push(@transfer_acl, $elt); push(@transfer_comments, $comment); } $have_options = 1; } elsif ($directive eq "sortlist") { if ($comment ne "") { $comment = "\t$comment"; } foreach $elt (@rest) { push(@topology, $elt); push(@topology_comments, $comment); } } elsif ($directive eq "bogusns") { if ($comment ne "") { $comment = "\t$comment"; } foreach $elt (@rest) { push(@bogus, $elt); push(@bogus_comments, $comment); } } elsif ($directive eq "max-fetch") { $options{"transfers-in"}=$rest[0]; $options_comments{"transfers-in"}=$comment; $have_options = 1; } else { $new_config .= "// NOTE: unconverted directive '$directive @rest'\n\n"; } } print "// generated by named-bootconf.pl\n\n"; if ($have_options) { print "options {\n"; foreach $option (sort(keys(%options))) { print "\t$option $options{$option};"; if ($options_comments{$option} ne "") { print "\t$options_comments{$option}"; } print "\n"; } if (@transfer_acl > 0) { print "\tallow-transfer {\n"; for ($i = 0; $i <= $#transfer_acl; $i++) { &print_maybe_masked("\t\t", $transfer_acl[$i], $transfer_comments[$i]); } print "\t};\n"; } print "\t/* \t * If there is a firewall between you and nameservers you want \t * to talk to, you might need to uncomment the query-source \t * directive below. Previous versions of BIND always asked \t * questions using port 53, but BIND 8.1 uses an unprivileged \t * port by default. \t */ \t// query-source address * port 53; "; print "};\n\n"; } if ($logging ne "") { print "logging {\n$logging};\n\n"; } if (@topology > 0) { print "// Note: the following will be supported in a future release.\n"; print "/*\n"; print "host { any; } {\n\ttopology {\n"; for ($i = 0; $i <= $#topology; $i++) { &print_maybe_masked("\t\t", $topology[$i], $topology_comments[$i]); } print "\t};\n};\n"; print "*/\n"; print "\n"; } if (@bogus > 0) { for ($i = 0; $i <= $#bogus; $i++) { print "server $bogus[$i] { bogus yes; };$bogus_comments[$i]\n"; } print "\n"; } print $new_config; exit 0; sub maybe_print_comment { $prefix = shift; $suffix = shift; if ($comment ne "") { $new_config .= sprintf("%s%s%s", $prefix, $comment, $suffix); } } sub handle_options { foreach $option (@_) { if ($option eq "forward-only") { $options{"forward"}="only"; $options_comments{"forward"}=$comment; $have_options = 1; } elsif ($option eq "no-recursion") { $options{"recursion"}="no"; $options_comments{"recursion"}=$comment; $have_options = 1; } elsif ($option eq "no-fetch-glue") { $options{"fetch-glue"}="no"; $options_comments{"fetch-glue"}=$comment; $have_options = 1; } elsif ($option eq "fake-iquery") { $options{"fake-iquery"}="yes"; $options_comments{"fake-iquery"}=$comment; $have_options = 1; } elsif ($option eq "query-log") { if ($comment ne "") { $logging .= "\t$comment\n"; } $logging .= "\tcategory queries { default_syslog; };\n"; } else { $options{"// NOTE: unconverted option '$option'"}=""; $options_comments{"// NOTE: unconverted option '$option'"}= $comment; $have_options = 1; } } } sub handle_limit { $limit = shift; if ($limit eq "datasize" || $limit eq "transfers-in" || $limit eq "transfers-per-ns" || $limit eq "files") { $options{$limit}=$_[0]; $options_comments{$limit}=$comment; $have_options = 1; } else { $options{"// NOTE: unconverted limit '$limit @_'"}=""; $options_comments{"// NOTE: unconverted limit '$limit @_'"}=$comment; $have_options = 1; } } sub print_maybe_masked { # this assumes a contiguous netmask starting at the MSB $prefix = shift; $elt = shift; $elt_comment = shift; if ($elt =~ /^(.*)&(.*)$/) { $address = $1; $mask = $2; ($m1,$m2,$m3,$m4) = split(/\./, $mask); $mask_val = ($m1 << 24) + ($m2 << 16) +($m3 << 8) + $m4; $zero_bits = 0; while (($mask_val % 2) == 0) { $mask_val /= 2; $zero_bits++; } $mask_bits = 32 - $zero_bits; } else { $address = $elt; ($a1,$a2,$a3,$a4) = split(/\./, $address); if ($a1 < 128) { $mask_bits = 8; } elsif ($a1 < 192) { $mask_bits = 16; } else { $mask_bits = 24; } } print "$prefix$address"; if ($mask_bits != 32) { print "/$mask_bits"; } print ";$elt_comment\n"; }