package Net::DNS::Resolver::Win32;
use strict;
use vars qw(@ISA $VERSION);
use Net::DNS::Resolver::Base ();
@ISA = qw(Net::DNS::Resolver::Base);
$VERSION = (qw$LastChangedRevision: 588 $)[1];
use Win32::Registry;
sub init {
my $debug=0;
my ($class) = @_;
my $defaults = $class->defaults;
my ($resobj, %keys);
my $root = 'SYSTEM\CurrentControlSet\Services\Tcpip\Parameters';
unless ($main::HKEY_LOCAL_MACHINE->Open($root, $resobj)) {
$root = 'SYSTEM\CurrentControlSet\Services\VxD\MSTCP';
$main::HKEY_LOCAL_MACHINE->Open($root, $resobj)
or Carp::croak "can't read registry: $!";
}
$resobj->GetValues(\%keys)
or Carp::croak "can't read registry values: $!";
my $domain = $keys{'Domain'}->[2] || $keys{'DhcpDomain'}->[2] || '';
my $searchlist = "$domain ";
$searchlist .= $keys{'SearchList'}->[2];
my $nt4nameservers = $keys{'NameServer'}->[2] || $keys{'DhcpNameServer'}->[2];
my $nameservers = "";
my $bind_linkage;
my @sorted_interfaces;
print ";; DNS: Getting sorted interface list\n" if $debug;
$main::HKEY_LOCAL_MACHINE->Open('SYSTEM\CurrentControlSet\Services\Tcpip\Linkage',
$bind_linkage);
if($bind_linkage){
my $bind_linkage_list;
my $type;
$bind_linkage->QueryValueEx('Bind', $type, $bind_linkage_list);
if($bind_linkage_list){
@sorted_interfaces = split(m/[^\w{}\\-]+/s, $bind_linkage_list);
}
foreach my $interface (@sorted_interfaces){
$interface =~ s/^\\device\\//i;
print ";; DNS:Interface: $interface\n" if $debug;
}
}
my $interfaces;
$resobj->Open("Interfaces", $interfaces);
if ($interfaces) {
my @ifacelist;
if(@sorted_interfaces){
@ifacelist = @sorted_interfaces;
}else{
$interfaces->GetKeys(\@ifacelist);
}
foreach my $iface (@ifacelist) {
my $regiface;
$interfaces->Open($iface, $regiface);
if ($regiface) {
my $ns;
my $type;
my $ip;
my $ipdhcp;
$regiface->QueryValueEx("IPAddress", $type, $ip);
$regiface->QueryValueEx("DhcpIPAddress", $type, $ipdhcp);
if (($ip && !($ip =~ /0\.0\.0\.0/)) || ($ipdhcp && !($ipdhcp =~ /0\.0
\.0\.0/))) {
$regiface->QueryValueEx("NameServer", $type, $ns);
$regiface->QueryValueEx("DhcpNameServer", $type, $ns) unless $ns;
$nameservers .= " $ns" if $ns;
}
}
}
}
if (!$nameservers) {
$nameservers = $nt4nameservers;
}
if ($domain) {
$defaults->{'domain'} = $domain;
}
my $usedevolution = $keys{'UseDomainNameDevolution'}->[2];
if ($searchlist) {
my @a;
my %h;
foreach my $entry (split(m/[\s,]+/, $searchlist)) {
push(@a, $entry) unless $h{$entry};
$h{$entry} = 1;
if ($usedevolution) {
while ($entry =~ m $entry =~ s push(@a, $entry) unless $h{$entry};
$h{$entry} = 1;
}
}
}
$defaults->{'searchlist'} = \@a;
}
if ($nameservers) {
my @a;
my %h;
foreach my $ns (split(m/[\s,]+/, $nameservers)) {
push @a, $ns unless (!$ns || $h{$ns});
$h{$ns} = 1;
}
$defaults->{'nameservers'} = [map { m/(.*)/ } @a];
}
$class->read_env;
if (!$defaults->{'domain'} && @{$defaults->{'searchlist'}}) {
$defaults->{'domain'} = $defaults->{'searchlist'}[0];
} elsif (!@{$defaults->{'searchlist'}} && $defaults->{'domain'}) {
$defaults->{'searchlist'} = [ $defaults->{'domain'} ];
}
}
1;
__END__
=head1 NAME
Net::DNS::Resolver::Win32 - Windows Resolver Class
=head1 SYNOPSIS
use Net::DNS::Resolver;
=head1 DESCRIPTION
This class implements the windows specific portions of C<Net::DNS::Resolver>.
No user serviceable parts inside, see L<Net::DNS::Resolver|Net::DNS::Resolver>
for all your resolving needs.
=head1 COPYRIGHT
Copyright (c) 1997-2002 Michael Fuhr.
Portions Copyright (c) 2002-2004 Chris Reinhardt.
All rights reserved. This program is free software; you may redistribute
it and/or modify it under the same terms as Perl itself.
=head1 SEE ALSO
L<perl(1)>, L<Net::DNS>, L<Net::DNS::Resolver>
=cut