source: trunk/bind-import@ 809

Last change on this file since 809 was 809, checked in by Kris Deugau, 4 years ago

/trunk

Second sampled historic iteration of bind-import

File size: 3.1 KB
Line 
1#!/usr/bin/perl
2# Import a BIND zone file
3##
4# Copyright 2020 Kris Deugau <kdeugau@deepnet.cx>
5#
6# This program is free software: you can redistribute it and/or modify
7# it under the terms of the GNU General Public License as published by
8# the Free Software Foundation, either version 3 of the License, or
9# (at your option) any later version.
10#
11# This program is distributed in the hope that it will be useful,
12# but WITHOUT ANY WARRANTY; without even the implied warranty of
13# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14# GNU General Public License for more details.
15#
16# You should have received a copy of the GNU General Public License
17# along with this program. If not, see <http://www.gnu.org/licenses/>.
18##
19
20use strict;
21use warnings;
22use Data::Dumper;
23
24use lib '.';
25use DNSDB;
26
27my $dnsdb = new DNSDB;
28
29#print Dumper(\%reverse_typemap);
30
31my $zname = shift @ARGV;
32my $rev = 'n';
33my $zid;
34
35if ($zname =~ /\.arpa\.?$/ || $zname =~ m,^[\d./]+$,) {
36 $rev = 'y';
37 $zname = _zone2cidr($zname) if $zname =~ /\.arpa\.?$/;
38 $zid = $dnsdb->revID($zname,':ANY:');
39 if ($zid) {
40 $zname = new NetAddr::IP $zname;
41 $zname = DNSDB::_ZONE($zname, 'ZONE', 'r', '.').($zname->{isv6} ? '.ip6.arpa' : '.in-addr.arpa');
42 }
43} else {
44 $zid = $dnsdb->domainID($zname,':ANY:');
45}
46
47die "zone $zname not on file\n" if !$zid;
48
49##fixme: retrieve defttl from SOA record
50my $zonettl = 900;
51
52while (<>) {
53 next if /^\s*$/;
54 next if /^\s*;/;
55 my ($name) = /([\w_.-]+)\s/;
56 # append zone name to record name if missing AND not dot-terminated;
57 # this happens automagically for forward zones, but not reverse because Reasons. (fixme?)
58 # suck up and deal with the error if the dot-termiated name is out of zone; should be
59 # impossible with valid BIND zone file but...
60 $name .= ".$zname" if $name !~ /$zname$/ && $zname !~ /\.$/;
61 s/([\w_.-]+)\s+//;
62 my ($class) = /(IN|CS|CH|HS)\s/;
63 if ($class) {
64 if ($class ne 'IN') {
65 print "Non-Internet class records not supported, you weirdo\n";
66 next;
67 }
68 s/(IN|CS|CH|HS)\s+//;
69 } else {
70 $class = 'IN' if !$class;
71 }
72 my ($ttl) = /(\d+)?\s/;
73 if (defined $ttl) {
74 # TTL may be zero
75 s/(\d+)?\s+//;
76 } else {
77 # Fall back to zone default TTL
78 $ttl = $zonettl;
79 }
80 my ($type) = /([A-Z-]+)\s/;
81 if (!$reverse_typemap{$type}) {
82 print "Unknown type $type, skipping\n";
83 next;
84 }
85 my $itype = $reverse_typemap{$type};
86 s/([A-Z-]+)\s+//;
87 chomp;
88 my $rdata = $_;
89
90 # Quotes may arguably be syntactically required, but they're not actually part of the record data
91 if ($itype == 16) {
92 $rdata =~ s/^"//;
93 $rdata =~ s/"$//;
94 }
95
96no warnings qw(uninitialized);
97print "parsed: '$name' '$class' '$ttl' '$type'->'$itype' '$rdata'\t";
98#print;
99#;imap IN 900 CNAME deepnet.cx.
100##fixme: not sure how to handle the case where someone leaves off the class.
101 my ($code, $msg);
102 if ($rev eq 'n') {
103 ($code,$msg) = $dnsdb->addRec('n', $rev, $zid, \$name, \$itype, \$rdata, $ttl);
104 } else {
105 ($code,$msg) = $dnsdb->addRec('n', $rev, $zid, \$rdata, \$itype, \$name, $ttl);
106 }
107 print "$code: $msg\n";
108}
Note: See TracBrowser for help on using the repository browser.