Changeset 545 for branches/stable/tiny-import.pl
- Timestamp:
- 12/10/13 17:47:44 (10 years ago)
- Location:
- branches/stable
- Files:
-
- 1 edited
- 1 copied
Legend:
- Unmodified
- Added
- Removed
-
branches/stable
- Property svn:mergeinfo changed
/trunk merged: 264-316,318-416
- Property svn:mergeinfo changed
-
branches/stable/tiny-import.pl
r348 r545 19 19 ## 20 20 21 # WARNING: This is NOT a heavy-duty validator; it is assumed that the data 22 # being imported is more or less sane. Only minor structural validation will 23 # be done to weed out the most broken records. 24 21 25 use strict; 22 26 use warnings; … … 29 33 } 30 34 35 usage() if !@ARGV; 36 37 my %importcfg = ( 38 rw => 0, 39 conv => 0, 40 trial => 0, 41 ); 42 # Handle some command-line arguments 43 while ($ARGV[0] =~ /^-/) { 44 my $arg = shift @ARGV; 45 usage() if $arg !~ /^-[rct]+$/; 46 # -r rewrite imported files to comment imported records 47 # -c coerce/downconvert A+PTR = records to PTR 48 # -t trial mode; don't commit to DB or actually rewrite flatfile (disables -r) 49 $arg =~ s/^-//; 50 my @tmp = split //, $arg; 51 foreach (@tmp) { 52 $importcfg{rw} = 1 if $_ eq 'r'; 53 $importcfg{conv} = 1 if $_ eq 'c'; 54 $importcfg{trial} = 1 if $_ eq 't'; 55 } 56 } 57 $importcfg{rw} = 0 if $importcfg{trial}; 58 59 sub usage { 60 die q(usage: tiny-import.pl [-r] [-c] datafile1 datafile2 ... datafileN ... 61 -r Rewrite all specified data files with a warning header indicating the 62 records are now managed by web, and commenting out all imported records. 63 The directory containing any given datafile must be writable. 64 -c Convert any A+PTR (=) record to a bare PTR if the forward domain is 65 not present in the database. Note this does NOT look forward through 66 a single file, nor across multiple files handled in the same run. 67 Multiple passes may be necessary if SOA and = records are heavily 68 intermixed and not clustered together. 69 -t Trial run mode; spits out records that would be left unimported. 70 Disables -r if set. 71 72 -r and -c may be combined (-rc) 73 74 datafileN is any tinydns record data file. 75 ); 76 } 77 31 78 my $code; 32 79 my ($dbh,$msg) = connectDB($config{dbname}, $config{dbuser}, $config{dbpass}, $config{dbhost}); … … 38 85 my %cnt; 39 86 my @deferred; 87 my $errstr = ''; 40 88 41 89 foreach my $file (@ARGV) { … … 43 91 import(file => $file); 44 92 # import(file => $file, nosoa => 1); 45 $dbh->rollback ;46 # $dbh->commit;93 $dbh->rollback if $importcfg{trial}; 94 $dbh->commit unless $importcfg{trial}; 47 95 }; 48 96 if ($@) { 49 print "bleh: $@\n"; 50 die "die harder\n"; 97 print "Failure trying to import $file: $@\n $errstr\n"; 98 unlink ".$file.$$" if $importcfg{rw}; # cleanup 99 $dbh->rollback; 51 100 } 52 101 } 53 102 54 foreach (keys %cnt) { 55 print " $_ $cnt{$_}\n"; 56 } 103 # print summary count of record types encountered 104 foreach (keys %cnt) { 105 print " $_ $cnt{$_}\n"; 106 } 57 107 58 108 exit 0; … … 61 111 our %args = @_; 62 112 my $flatfile = $args{file}; 113 my @fpath = split '/', $flatfile; 114 $fpath[$#fpath] = ".$fpath[$#fpath]"; 115 my $rwfile = join('/', @fpath);#.".$$"; 116 63 117 open FLAT, "<$flatfile"; 64 118 65 our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl) ". 66 " VALUES (?,?,?,?,?,?,?,?,?)"); 67 119 if ($importcfg{rw}) { 120 open RWFLAT, ">$rwfile" or die "Couldn't open tempfile $rwfile for rewriting: $!\n"; 121 print RWFLAT "# WARNING: Records in this file have been imported to the web UI.\n#\n"; 122 } 123 124 our $recsth = $dbh->prepare("INSERT INTO records (domain_id,rdns_id,host,type,val,distance,weight,port,ttl,location) ". 125 " VALUES (?,?,?,?,?,?,?,?,?,?)"); 126 127 my %deleg; 128 129 my $ok = 0; 68 130 while (<FLAT>) { 69 next if /^#/; 70 next if /^\s*$/; 131 if (/^#/ || /^\s*$/) { 132 print RWFLAT "#$_" if $importcfg{rw}; 133 next; 134 } 71 135 chomp; 72 recslurp($_); 73 } 74 75 # Try the deferred records again, once. 136 s/\s*$//; 137 my $recstat = recslurp($_); 138 $ok++ if $recstat; 139 if ($importcfg{rw}) { 140 if ($recstat) { 141 print RWFLAT "#$_\n"; 142 } else { 143 print RWFLAT "$_\n"; 144 } 145 } 146 } 147 148 # Move the rewritten flatfile in place of the original, so that any 149 # external export processing will pick up any remaining records. 150 if ($importcfg{rw}) { 151 close RWFLAT; 152 rename "$rwfile", $flatfile; 153 } 154 155 # Show the failed records 76 156 foreach (@deferred) { 77 # print "trying $_ again\n"; 78 recslurp($_, 1); 79 } 157 print "failed to import $_\n"; 158 } 159 160 ##fixme: hmm. can't write the record back to the flatfile in the 161 # main while above, then come down here and import it anyway, can we? 162 # # Try the deferred records again, once. 163 # foreach (@deferred) { 164 # print "trying $_ again\n"; 165 # recslurp($_, 1); 166 # } 167 168 # .. but we can at least say how many records weren't imported. 169 print "$ok OK, ".scalar(@deferred)." deferred records in $flatfile\n"; 170 $#deferred = -1; 171 80 172 81 173 # Sub for various nonstandard types with lots of pure bytes expressed in octal 82 # Takes a tinydns rdata string and count, returns a lis of $count bytes as well174 # Takes a tinydns rdata string and count, returns a list of $count bytes as well 83 175 # as trimming those logical bytes off the front of the rdata string. 84 176 sub _byteparse { … … 103 195 } 104 196 197 # Convert octal-coded bytes back to something resembling normal characters, general case 198 sub _deoctal { 199 my $targ = shift; 200 while ($$targ =~ /\\(\d{3})/) { 201 my $sub = chr(oct($1)); 202 $$targ =~ s/\\$1/$sub/g; 203 } 204 } 205 206 sub _rdata2string { 207 my $rdata = shift; 208 my $tmpout = ''; 209 while ($rdata) { 210 my $bytecount = 0; 211 if ($rdata =~ /^\\/) { 212 ($bytecount) = ($rdata =~ /^(\\\d{3})/); 213 $bytecount =~ s/\\/0/; 214 $bytecount = oct($bytecount); 215 $rdata =~ s/^\\\d{3}//; 216 } else { 217 ($bytecount) = ($rdata =~ /^(.)/); 218 $bytecount = ord($bytecount); 219 $rdata =~ s/^.//; 220 } 221 my @tmp = _byteparse(\$rdata, $bytecount); 222 foreach (@tmp) { $tmpout .= chr($_); } 223 ##fixme: warn or fail on long (>256? >512? >321?) strings 224 } 225 return $tmpout; 226 } 227 228 sub _rdata2hex { 229 my $rdata = shift; 230 my $tmpout = ''; 231 while ($rdata) { 232 my $byte = ''; 233 if ($rdata =~ /^\\/) { 234 ($byte) = ($rdata =~ /^(\\\d{3})/); 235 $byte =~ s/\\/0/; 236 $tmpout .= sprintf("%0.2x", oct($byte)); 237 $rdata =~ s/^\\\d{3}//; 238 } else { 239 ($byte) = ($rdata =~ /^(.)/); 240 $tmpout .= sprintf("%0.2x", ord($byte)); 241 $rdata =~ s/^.//; 242 } 243 } 244 return $tmpout; 245 } 246 247 105 248 sub recslurp { 106 249 my $rec = shift; 107 250 my $nodefer = shift || 0; 251 my $impok = 1; 252 253 $errstr = $rec; # this way at least we have some idea what went <splat> 108 254 109 255 if ($rec =~ /^=/) { 110 256 $cnt{APTR}++; 111 if ($rec !~ /^=(?:\*|\\052)?[a-z0-9\._-]+:[\d\.]+:\d*/i) { 112 print "bad A+PTR $rec\n"; 113 return; 114 #=sud-rr-iGi0-1_sud-gw1-iGi4-2.vianet.ca::10.10.10.13:900::in 115 } 116 my ($host,$ip,$ttl,$time,$loc) = split /:/, $rec; 257 258 ##fixme: do checks like this for all types 259 if ($rec !~ /^=(?:\*|\\052)?[a-z0-9\._-]+:[\d\.]+:\d*/i) { 260 print "bad A+PTR $rec\n"; 261 return; 262 } 263 my ($host,$ip,$ttl,$stamp,$loc) = split /:/, $rec, 5; 117 264 $host =~ s/^=//; 118 265 $host =~ s/\.$//; 119 $time = '' if !$time; 120 $loc = '' if !$loc; 121 print "bleh, bad A+PTR! $rec\n" if $loc =~ /:/; 266 $ttl = 0 if !$ttl; 267 $stamp = '' if !$stamp; 268 $loc = '' if !$loc; 269 $loc = '' if $loc =~ /^:+$/; 122 270 my $fparent = DNSDB::_hostparent($dbh, $host); 123 271 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($ip)); 124 272 if ($fparent && $rparent) { 125 $dbh->do("INSERT INTO records (domain_id,rdns_id,host,type,val,ttl) VALUES (?,?,?,?,?,?)", undef, 126 ($fparent, $rparent, $host, 65280, $ip, $ttl)); 273 $recsth->execute($fparent, $rparent, $host, 65280, $ip, 0, 0, 0, $ttl, $loc); 127 274 } else { 128 275 push @deferred, $rec unless $nodefer; 276 $impok = 0; 129 277 # print "$tmporig deferred; can't find both forward and reverse zone parents\n"; 130 278 } … … 132 280 } elsif ($rec =~ /^C/) { 133 281 $cnt{CNAME}++; 134 my ($host,$targ,$ttl,$time,$loc) = split /:/, $rec; 282 283 my ($host,$targ,$ttl,$stamp,$loc) = split /:/, $rec, 5; 135 284 $host =~ s/^C//; 136 285 $host =~ s/\.$//; 137 $time = '' if !$time; 138 $loc = '' if !$loc; 139 my $fparent = DNSDB::_hostparent($dbh, $host); 140 if ($fparent) { 141 142 } else { 143 push @deferred, $rec unless $nodefer; 144 # print "$tmporig deferred; can't find parent zone\n"; 286 $host =~ s/^\\052/*/; 287 $ttl = 0 if !$ttl; 288 $stamp = '' if !$stamp; 289 $loc = '' if !$loc; 290 $loc = '' if $loc =~ /^:+$/; 291 if ($host =~ /\.arpa$/) { 292 ($code,$msg) = DNSDB::_zone2cidr($host); 293 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 294 $recsth->execute(0, $rparent, $targ, 5, $msg->addr, 0, 0, 0, $ttl, $loc); 295 296 ##fixme: automagically convert manually maintained sub-/24 delegations 297 # my ($subip, $zone) = split /\./, $targ, 2; 298 # ($code, $msg) = DNSDB::_zone2cidr($zone); 299 # push @{$deleg{"$msg"}{iplist}}, $subip; 300 #print "$msg $subip\n"; 301 302 } else { 303 my $fparent = DNSDB::_hostparent($dbh, $host); 304 if ($fparent) { 305 $recsth->execute($fparent, 0, $host, 5, $targ, 0, 0, 0, $ttl, $loc); 306 } else { 307 push @deferred, $rec unless $nodefer; 308 $impok = 0; 309 # print "$tmporig deferred; can't find parent zone\n"; 310 } 145 311 } 146 312 147 313 } elsif ($rec =~ /^\&/) { 148 314 $cnt{NS}++; 315 316 my ($zone,$ip,$ns,$ttl,$stamp,$loc) = split /:/, $rec, 6; 317 $zone =~ s/^\&//; 318 $zone =~ s/\.$//; 319 $ns =~ s/\.$//; 320 $ns = "$ns.ns.$zone" if $ns !~ /\./; 321 $ttl = 0 if !$ttl; 322 $stamp = '' if !$stamp; 323 $loc = '' if !$loc; 324 $loc = '' if $loc =~ /^:+$/; 325 if ($zone =~ /\.arpa$/) { 326 ($code,$msg) = DNSDB::_zone2cidr($zone); 327 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >>= ?", undef, ("$msg")); 328 ##fixme, in concert with the CNAME check for same; automagically 329 # create "delegate" record instead for subzone NSes: convert above to use = instead of >>= 330 # ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ("$msg")) 331 # if !$rparent; 332 if ($rparent) { 333 $recsth->execute(0, $rparent, $ns, 2, $msg, 0, 0, 0, $ttl, $loc); 334 } else { 335 push @deferred, $rec unless $nodefer; 336 $impok = 0; 337 } 338 } else { 339 my $fparent = DNSDB::_hostparent($dbh, $zone); 340 if ($fparent) { 341 $recsth->execute($fparent, 0, $zone, 2, $ns, 0, 0, 0, $ttl, $loc); 342 $recsth->execute($fparent, 0, $ns, 2, $ip, 0, 0, 0, $ttl, $loc) if $ip; 343 } else { 344 push @deferred, $rec unless $nodefer; 345 $impok = 0; 346 } 347 } 348 149 349 } elsif ($rec =~ /^\^/) { 150 350 $cnt{PTR}++; 351 352 my ($rip,$host,$ttl,$stamp,$loc) = split /:/, $rec, 5; 353 $rip =~ s/^\^//; 354 $rip =~ s/\.$//; 355 $ttl = 0 if !$ttl; 356 $stamp = '' if !$stamp; 357 $loc = '' if !$loc; 358 $loc = '' if $loc =~ /^:+$/; 359 my $rparent; 360 if (my ($i, $z) = ($rip =~ /^(\d+)\.(\d+-(?:\d+\.){4}in-addr.arpa)$/) ) { 361 ($code,$msg) = DNSDB::_zone2cidr($z); 362 # Exact matches only, because we're in a sub-/24 delegation 363 ##fixme: flag the type of delegation (range, subnet-with-dash, subnet-with-slash) 364 # somewhere so we can recover it on export. probably best to do that in the revzone data. 365 ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet = ?", undef, ("$msg")); 366 $z =~ s/^[\d-]+//; 367 ($code,$msg) = DNSDB::_zone2cidr("$i.$z"); # Get the actual IP and normalize 368 } else { 369 ($code,$msg) = DNSDB::_zone2cidr($rip); 370 ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ("$msg")); 371 } 372 if ($rparent) { 373 $recsth->execute(0, $rparent, $host, 12, $msg->addr, 0, 0, 0, $ttl, $loc); 374 } else { 375 push @deferred, $rec unless $nodefer; 376 $impok = 0; 377 } 378 151 379 } elsif ($rec =~ /^\+/) { 152 380 $cnt{A}++; 381 382 my ($host,$ip,$ttl,$stamp,$loc) = split /:/, $rec, 5; 383 $host =~ s/^\+//; 384 $host =~ s/\.$//; 385 $host =~ s/^\\052/*/; 386 $ttl = 0 if !$ttl; 387 $stamp = '' if !$stamp; 388 $loc = '' if !$loc; 389 $loc = '' if $loc =~ /^:+$/; 390 391 my $domid = DNSDB::_hostparent($dbh, $host); 392 if ($domid) { 393 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc); 394 } else { 395 push @deferred, $rec unless $nodefer; 396 $impok = 0; 397 } 398 153 399 } elsif ($rec =~ /^Z/) { 154 400 $cnt{SOA}++; 155 #Z128.91.209.in-addr.arpa:ns1.vianet.ca.:dnsadmin.vianet.ca.::1209600:1209600:900:900:900: 156 my ($zone,$master,$contact,$serial,$refresh,$retry,$expire,$minttl,$ttl,$ time,$loc) = split /:/, $rec;401 402 my ($zone,$master,$contact,$serial,$refresh,$retry,$expire,$minttl,$ttl,$stamp,$loc) = split /:/, $rec, 11; 157 403 $zone =~ s/^Z//; 158 404 $zone =~ s/\.$//; 159 405 $master =~ s/\.$//; 160 406 $contact =~ s/\.$//; 161 $time = '' if !$time; 162 $loc = '' if !$loc; 407 $ttl = 0 if !$ttl; 408 $stamp = '' if !$stamp; 409 $loc = '' if !$loc; 410 $loc = '' if $loc =~ /^:+$/; 163 411 if ($zone =~ /\.arpa$/) { 164 412 ($code,$msg) = DNSDB::_zone2cidr($zone); 165 $dbh->do("INSERT INTO revzones (revnet,group_id,status) VALUES (?,1,1)", undef, ($msg)); 413 $dbh->do("INSERT INTO revzones (revnet,group_id,status,default_location) VALUES (?,1,1,?)", 414 undef, ($msg, $loc)); 166 415 my ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')"); 167 $dbh->do("INSERT INTO records (rdns_id,host,type,val,ttl) VALUES (?,?,6,?,?)", undef, 168 ($rdns, "$contact:$master", "$refresh:$retry:$expire:$minttl", $ttl)); 169 } else { 170 $dbh->do("INSERT INTO domains (domain,group_id,status) VALUES (?,1,1)", undef, ($zone));416 $recsth->execute(0, $rdns, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc); 417 } else { 418 $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,1,1,?)", 419 undef, ($zone, $loc)); 171 420 my ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')"); 172 $dbh->do("INSERT INTO records (rdns_id,host,type,val,ttl) VALUES (?,?,6,?,?)", undef, 173 ($domid, "$contact:$master", "$refresh:$retry:$expire:$minttl", $ttl)); 421 $recsth->execute($domid, 0, "$contact:$master", 6, "$refresh:$retry:$expire:$minttl", 0, 0, 0, $ttl, $loc); 174 422 } 175 423 176 424 } elsif ($rec =~ /^\@/) { 177 425 $cnt{MX}++; 426 427 my ($zone,$ip,$host,$dist,$ttl,$stamp,$loc) = split /:/, $rec, 7; 428 $zone =~ s/^\@//; 429 $zone =~ s/\.$//; 430 $zone =~ s/^\\052/*/; 431 $host =~ s/\.$//; 432 $host = "$host.mx.$zone" if $host !~ /\./; 433 $ttl = 0 if !$ttl; 434 $stamp = '' if !$stamp; 435 $loc = '' if !$loc; 436 $loc = '' if $loc =~ /^:+$/; 437 438 # note we don't check for reverse domains here, because MX records don't make any sense in reverse zones. 439 # if this really ever becomes an issue for someone it can be expanded to handle those weirdos 440 441 # allow for subzone MXes, since it's perfectly legitimate to simply stuff it all in a single parent zone 442 my $domid = DNSDB::_hostparent($dbh, $zone); 443 if ($domid) { 444 $recsth->execute($domid, 0, $zone, 15, $host, $dist, 0, 0, $ttl, $loc); 445 $recsth->execute($domid, 0, $host, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip; 446 } else { 447 push @deferred, $rec unless $nodefer; 448 $impok = 0; 449 } 450 178 451 } elsif ($rec =~ /^'/) { 179 452 $cnt{TXT}++; 180 453 181 sub _deoctal { 182 my $targ = shift; 183 while ($$targ =~ /\\(\d{3})/) { 184 my $sub = chr(oct($1)); 185 $$targ =~ s/\\$1/$sub/g; 186 } 187 } 188 189 my ($fqdn, $rdata, $ttl, $time, $loc) = split /:/, $rec; 454 my ($fqdn, $rdata, $ttl, $stamp, $loc) = split /:/, $rec, 5; 190 455 $fqdn =~ s/^'//; 456 $fqdn =~ s/^\\052/*/; 191 457 _deoctal(\$rdata); 192 193 print "$fqdn TXT '$rdata'\n" if $fqdn =~ /^\*/; 194 my $domid = DNSDB::_hostparent($dbh, $fqdn); 195 if ($domid) { 196 $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl); 197 } else { 198 push @deferred, $rec unless $nodefer; 458 $ttl = 0 if !$ttl; 459 $stamp = '' if !$stamp; 460 $loc = '' if !$loc; 461 $loc = '' if $loc =~ /^:+$/; 462 463 if ($fqdn =~ /\.arpa$/) { 464 ($code,$msg) = DNSDB::_zone2cidr($fqdn); 465 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 466 $recsth->execute(0, $rparent, $rdata, 16, "$msg", 0, 0, 0, $ttl, $loc); 467 } else { 468 my $domid = DNSDB::_hostparent($dbh, $fqdn); 469 if ($domid) { 470 $recsth->execute($domid, 0, $fqdn, 16, $rdata, 0, 0, 0, $ttl, $loc); 471 } else { 472 push @deferred, $rec unless $nodefer; 473 $impok = 0; 474 } 199 475 } 200 476 201 477 } elsif ($rec =~ /^\./) { 202 478 $cnt{NSASOA}++; 479 480 my ($fqdn, $ip, $ns, $ttl, $stamp, $loc) = split /:/, $rec, 6; 481 $fqdn =~ s/^\.//; 482 $fqdn =~ s/\.$//; 483 $ns =~ s/\.$//; 484 $ns = "$ns.ns.$fqdn" if $ns !~ /\./; 485 $ttl = 0 if !$ttl; 486 $stamp = '' if !$stamp; 487 $loc = '' if !$loc; 488 $loc = '' if $loc =~ /^:+$/; 489 490 if ($fqdn =~ /\.arpa$/) { 491 ($code,$msg) = DNSDB::_zone2cidr($fqdn); 492 my ($rdns) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet = ?", undef, ($msg)); 493 if (!$rdns) { 494 $errstr = "adding revzone $msg"; 495 $dbh->do("INSERT INTO revzones (revnet,group_id,status,default_location) VALUES (?,1,1,?)", 496 undef, ($msg, $loc)); 497 ($rdns) = $dbh->selectrow_array("SELECT currval('revzones_rdns_id_seq')"); 498 # this would probably make a lot more sense to do hostmaster.$config{admindomain} 499 $recsth->execute(0, $rdns, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", $loc); 500 } 501 $recsth->execute(0, $rdns, $ns, 2, "$msg", 0, 0, 0, $ttl, $loc); 502 ##fixme: (?) implement full conversion of tinydns . records? 503 # -> problem: A record for NS must be added to the appropriate *forward* zone, not the reverse 504 #$recsth->execute(0, $rdns, $ns, 1, $ip, 0, 0, 0, $ttl) 505 # ... auto-A-record simply does not make sense in reverse zones. Functionally 506 # I think it would work, sort of, but it's a nasty mess and anyone hosting reverse 507 # zones has names for their nameservers already. 508 # Even the auto-nameserver-fqdn comes out... ugly. 509 510 } else { 511 my ($domid) = $dbh->selectrow_array("SELECT domain_id FROM domains WHERE lower(domain) = lower(?)", 512 undef, ($fqdn)); 513 if (!$domid) { 514 $errstr = "adding domain $fqdn"; 515 $dbh->do("INSERT INTO domains (domain,group_id,status,default_location) VALUES (?,1,1,?)", 516 undef, ($fqdn, $loc)); 517 ($domid) = $dbh->selectrow_array("SELECT currval('domains_domain_id_seq')"); 518 $recsth->execute($domid, 0, "hostmaster.$fqdn:$ns", 6, "16384:2048:1048576:2560", 0, 0, 0, "2560", $loc); 519 } 520 $recsth->execute($domid, 0, $fqdn, 2, $ns, 0, 0, 0, $ttl, $loc); 521 $recsth->execute($domid, 0, $ns, 1, $ip, 0, 0, 0, $ttl, $loc) if $ip; 522 } 523 524 525 } elsif ($rec =~ /^\%/) { 526 $cnt{VIEWS}++; 527 528 # unfortunate that we don't have a guaranteed way to get a description on these. :/ 529 my ($loc,$cnet) = split /:/, $rec, 2; 530 $loc =~ s/^\%//; 531 if (my ($iplist) = $dbh->selectrow_array("SELECT iplist FROM locations WHERE location = ?", undef, ($loc))) { 532 if ($cnet) { 533 $iplist .= ", $cnet"; 534 $dbh->do("UPDATE locations SET iplist = ? WHERE location = ?", undef, ($iplist, $loc)); 535 } else { 536 # hmm. spit out a warning? if we already have entries for $loc, adding a null 537 # entry will almost certainly Do The Wrong Thing(TM) 538 } 539 } else { 540 $cnet = '' if !$cnet; # de-nullify 541 $dbh->do("INSERT INTO locations (location,iplist,description) VALUES (?,?,?)", undef, ($loc, $cnet, $loc)); 542 } 543 203 544 } elsif ($rec =~ /^:/) { 204 545 $cnt{NCUST}++; … … 206 547 # recognition and handling for the core common types, this must deal with the leftovers. 207 548 # :fqdn:type:rdata:ttl:time:loc 208 #:mx2.sys.vianet.ca:44:\001\001\215\272\152\152\123\142\120\071\320\106\160\364\107\372\153\116\036\111\247\135:900::sys 209 #:_sipfederationtls._tcp.ncstechnology.com:33:\000\144\000\001\023\305\006sipfed\006online\004lync\003com\000:3600:: 210 211 my (undef, $fqdn, $type, $rdata, $ttl, $time, $loc) = split /:/, $rec; 212 213 if ($type == 33) { 214 # SRV 215 my ($prio, $weight, $port, $target) = (0,0,0,0); 216 217 my @tmp = _byteparse(\$rdata, 2); 218 $prio = $tmp[0] * 256 + $tmp[1]; 219 @tmp = _byteparse(\$rdata, 2); 220 $weight = $tmp[0] * 256 + $tmp[1]; 221 @tmp = _byteparse(\$rdata, 2); 222 $port = $tmp[0] * 256 + $tmp[1]; 223 224 $rdata =~ s/\\\d{3}/./g; 225 ($target) = ($rdata =~ /^\.(.+)\.$/); 549 550 my (undef, $fqdn, $type, $rdata, $ttl, $stamp, $loc) = split /:/, $rec, 7; 551 $fqdn =~ s/\.$//; 552 $fqdn =~ s/^\\052/*/; 553 $ttl = 0 if !$ttl; 554 $stamp = '' if !$stamp; 555 $loc = '' if !$loc; 556 $loc = '' if $loc =~ /^:+$/; 557 558 if ($type == 33) { 559 # SRV 560 my ($prio, $weight, $port, $target) = (0,0,0,0); 561 562 my @tmp = _byteparse(\$rdata, 2); 563 $prio = $tmp[0] * 256 + $tmp[1]; 564 @tmp = _byteparse(\$rdata, 2); 565 $weight = $tmp[0] * 256 + $tmp[1]; 566 @tmp = _byteparse(\$rdata, 2); 567 $port = $tmp[0] * 256 + $tmp[1]; 568 569 $rdata =~ s/\\\d{3}/./g; 570 ($target) = ($rdata =~ /^\.(.+)\.$/); 226 571 # hmm. the above *should* work, but What If(TM) we have ASCII-range bytes 227 572 # representing the target's fqdn part length(s)? axfr-get doesn't seem to, … … 236 581 # } 237 582 238 my $domid = DNSDB::_hostparent($dbh, $fqdn); 239 if ($domid) { 240 $recsth->execute($domid, 0, $fqdn, $type, $target, $prio, $weight, $port, $ttl) if $domid; 241 } else { 242 push @deferred, $rec unless $nodefer; 243 } 244 245 } elsif ($type == 28) { 246 # AAAA 247 248 my @v6; 249 250 for (my $i=0; $i < 8; $i++) { 251 my @tmp = _byteparse(\$rdata, 2); 252 push @v6, sprintf("%0.4x", $tmp[0] * 256 + $tmp[1]); 253 } 254 my $val = NetAddr::IP->new(join(':', @v6)); 255 256 my $domid = DNSDB::_hostparent($dbh, $fqdn); 257 if ($domid) { 258 $recsth->execute($domid, 0, $fqdn, $type, $val->addr, 0, 0, 0, $ttl) if $domid; 259 } else { 260 push @deferred, $rec unless $nodefer; 261 } 262 263 } else { 264 # ... uhhh, dunno 265 } 583 my $domid = DNSDB::_hostparent($dbh, $fqdn); 584 if ($domid) { 585 $recsth->execute($domid, 0, $fqdn, 33, $target, $prio, $weight, $port, $ttl, $loc) if $domid; 586 } else { 587 push @deferred, $rec unless $nodefer; 588 $impok = 0; 589 } 590 591 } elsif ($type == 28) { 592 # AAAA 593 my @v6; 594 595 for (my $i=0; $i < 8; $i++) { 596 my @tmp = _byteparse(\$rdata, 2); 597 push @v6, sprintf("%0.4x", $tmp[0] * 256 + $tmp[1]); 598 } 599 my $val = NetAddr::IP->new(join(':', @v6)); 600 601 my $fparent = DNSDB::_hostparent($dbh, $fqdn); 602 if ($fparent) { 603 $recsth->execute($fparent, 0, $fqdn, 28, $val->addr, 0, 0, 0, $ttl, $loc); 604 } else { 605 push @deferred, $rec unless $nodefer; 606 $impok = 0; 607 } 608 609 } elsif ($type == 16) { 610 # TXT 611 my $txtstring = _rdata2string($rdata); 612 613 if ($fqdn =~ /\.arpa$/) { 614 ($code,$msg) = DNSDB::_zone2cidr($fqdn); 615 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 616 if ($rparent) { 617 $recsth->execute(0, $rparent, $txtstring, 16, "$msg", 0, 0, 0, $ttl, $loc); 618 } else { 619 push @deferred, $rec unless $nodefer; 620 $impok = 0; 621 } 622 } else { 623 my $domid = DNSDB::_hostparent($dbh, $fqdn); 624 if ($domid) { 625 $recsth->execute($domid, 0, $fqdn, 16, $txtstring, 0, 0, 0, $ttl, $loc); 626 } else { 627 push @deferred, $rec unless $nodefer; 628 $impok = 0; 629 } 630 } 631 632 } elsif ($type == 17) { 633 # RP 634 my ($email, $txtrec) = split /\\000/, $rdata; 635 $email =~ s/\\\d{3}/./g; 636 $email =~ s/^\.//; 637 $txtrec =~ s/\\\d{3}/./g; 638 $txtrec =~ s/^\.//; 639 640 # these might actually make sense in a reverse zone... sort of. 641 if ($fqdn =~ /\.arpa$/) { 642 ($code,$msg) = DNSDB::_zone2cidr($fqdn); 643 my ($rparent) = $dbh->selectrow_array("SELECT rdns_id FROM revzones WHERE revnet >> ?", undef, ($msg)); 644 if ($rparent) { 645 $recsth->execute(0, $rparent, "$email $txtrec", 17, "$msg", 0, 0, 0, $ttl, $loc); 646 } else { 647 push @deferred, $rec unless $nodefer; 648 $impok = 0; 649 } 650 } else { 651 my $domid = DNSDB::_hostparent($dbh, $fqdn); 652 if ($domid) { 653 $recsth->execute($domid, 0, $fqdn, 17, "$email $txtrec", 0, 0, 0, $ttl, $loc); 654 } else { 655 push @deferred, $rec unless $nodefer; 656 $impok = 0; 657 } 658 } 659 660 } elsif ($type == 44) { 661 # SSHFP 662 my $sshfp = _byteparse(\$rdata, 1); 663 $sshfp .= " "._byteparse(\$rdata, 1); 664 $sshfp .= " "._rdata2hex($rdata); 665 666 # these do not make sense in a reverse zone, since they're logically attached to an A record 667 my $domid = DNSDB::_hostparent($dbh, $fqdn); 668 if ($domid) { 669 $recsth->execute($domid, 0, $fqdn, 44, $sshfp, 0, 0, 0, $ttl, $loc); 670 } else { 671 push @deferred, $rec unless $nodefer; 672 $impok = 0; 673 } 674 675 } else { 676 print "unhandled rec $rec\n"; 677 $impok = 0; 678 # ... uhhh, dunno 679 } 266 680 267 681 } else { 268 682 $cnt{other}++; 269 print " $_\n";683 print " $_\n"; 270 684 } 271 } 685 686 return $impok; # just to make sure 687 } # recslurp() 272 688 273 689 close FLAT;
Note:
See TracChangeset
for help on using the changeset viewer.