1*83ee113eSDavid van Moolenbroek#set ts=3 2*83ee113eSDavid van Moolenbroek# 3*83ee113eSDavid van Moolenbroek# ms2isc.pl 4*83ee113eSDavid van Moolenbroek# MS NT4 DHCP to ISC DHCP Configuration Migration Tool 5*83ee113eSDavid van Moolenbroek# 6*83ee113eSDavid van Moolenbroek# Author: Shu-Min Chang 7*83ee113eSDavid van Moolenbroek# 8*83ee113eSDavid van Moolenbroek# Copyright(c) 2003 Intel Corporation. All rights reserved 9*83ee113eSDavid van Moolenbroek# 10*83ee113eSDavid van Moolenbroek# Redistribution and use in source and binary forms, with or without 11*83ee113eSDavid van Moolenbroek# modification, are permitted provided that the following conditions are met: 12*83ee113eSDavid van Moolenbroek# 13*83ee113eSDavid van Moolenbroek# 1. Redistributions of source code must retain the above copyright notice, 14*83ee113eSDavid van Moolenbroek# this list of conditions and the following disclaimer. 15*83ee113eSDavid van Moolenbroek# 2. Redistributions in binary form must reproduce the above copyright notice 16*83ee113eSDavid van Moolenbroek# this list of conditions and the following disclaimer in the documentation 17*83ee113eSDavid van Moolenbroek# and/or other materials provided with the distribution 18*83ee113eSDavid van Moolenbroek# 3. Neither the name of Intel Corporation nor the names of its contributors 19*83ee113eSDavid van Moolenbroek# may be used to endorse or promote products derived from this software 20*83ee113eSDavid van Moolenbroek# without specific prior written permission. 21*83ee113eSDavid van Moolenbroek# 22*83ee113eSDavid van Moolenbroek# THIS SOFTWARE IS PROVIDED BY THE INTEL CORPORATION AND CONTRIBUTORS "AS IS" 23*83ee113eSDavid van Moolenbroek# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24*83ee113eSDavid van Moolenbroek# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25*83ee113eSDavid van Moolenbroek# ARE DISCLAIMED. IN NO EVENT SHALL THE INTEL CORPORATION OR CONTRIBUTORS BE 26*83ee113eSDavid van Moolenbroek# LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL EXEMPLARY, OR 27*83ee113eSDavid van Moolenbroek# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO PROCUREMENT OF SUBSTITUE 28*83ee113eSDavid van Moolenbroek# GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29*83ee113eSDavid van Moolenbroek# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30*83ee113eSDavid van Moolenbroek# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT 31*83ee113eSDavid van Moolenbroek# OF THE USE OF THIS SOFTWARE, EVEN IF ADVICED OF THE POSSIBILITY OF SUCH 32*83ee113eSDavid van Moolenbroek# DAMAGE. 33*83ee113eSDavid van Moolenbroek 34*83ee113eSDavid van Moolenbroekuse strict; 35*83ee113eSDavid van Moolenbroekuse Socket; 36*83ee113eSDavid van Moolenbroekuse Getopt::Std; 37*83ee113eSDavid van Moolenbroekuse Filehandle; 38*83ee113eSDavid van Moolenbroekuse Registry; # Custom Perl Module to make Registry access easier. 39*83ee113eSDavid van Moolenbroek 40*83ee113eSDavid van Moolenbroekmy $usage = << 'ENDOFHELP'; 41*83ee113eSDavid van Moolenbroek 42*83ee113eSDavid van MoolenbroekPurpose: A Perl Script converting MS NT4 DHCP configuration to ISC DHCP3 43*83ee113eSDavid van Moolenbroekconfiguration file by reading NT4's registry. 44*83ee113eSDavid van Moolenbroek 45*83ee113eSDavid van MoolenbroekRequires: Registry.pm and ActiveState 5.6.0 46*83ee113eSDavid van Moolenbroek 47*83ee113eSDavid van MoolenbroekUsage: $ARGV -s <Srv> -o <Out> [-p <Pri> [-k <key>]] [-f <Fo>] 48*83ee113eSDavid van Moolenbroek 49*83ee113eSDavid van Moolenbroek <Srv> Server IP or name for NT4 DHCP server to fetch the configuration from. 50*83ee113eSDavid van Moolenbroek <Out> Output filename for the configuration file. 51*83ee113eSDavid van Moolenbroek <Pri> Primary DNS server name for sending the dynamic DNS update to. 52*83ee113eSDavid van Moolenbroek <Key> Key name for use in updating the dynamic DNS zone. 53*83ee113eSDavid van Moolenbroek <Fo> Failover peer name shared with the DHCP partner. 54*83ee113eSDavid van Moolenbroek 55*83ee113eSDavid van MoolenbroekEssentially the <Srv> needs to be an NT4 (3.x should work but not tested) which 56*83ee113eSDavid van Moolenbroekyou should have registry read access to. You must run this script from a 57*83ee113eSDavid van MoolenbroekWindows machine because of the requirement to access the registry. 58*83ee113eSDavid van Moolenbroek 59*83ee113eSDavid van MoolenbroekThe <Pri> is optional parameter for desginating the dynamic DNS update if 60*83ee113eSDavid van Moolenbroekmissing then the "zone" section of the declaration will be skipped. The <Key> 61*83ee113eSDavid van Moolenbroekis needed if you've configured your DNS zone with a key, in addition, you'll 62*83ee113eSDavid van Moolenbroekneed to define that key in this DHCP configuration file elsewhere manually, 63*83ee113eSDavid van Moolenbroekread the DHCP Handbook to figure out what you need to define. 64*83ee113eSDavid van Moolenbroek 65*83ee113eSDavid van MoolenbroekThe <Fo> specifies the fail-over peer name in the pool section, you'll need to 66*83ee113eSDavid van Moolenbroekdefine additional detail elsewhere manually, again read the DHCP handbook. 67*83ee113eSDavid van Moolenbroek 68*83ee113eSDavid van MoolenbroekNOTE: the program only knows of the following global and subnet options: 69*83ee113eSDavid van Moolenbroek 3, 6, 15, 28, 44, and 46 70*83ee113eSDavid van Moolenbroek 71*83ee113eSDavid van Moolenbroek If it runs into options other than the known ones, it will quit. You 72*83ee113eSDavid van Moolenbroek may fix this by modifying the following procedures: 73*83ee113eSDavid van Moolenbroek GetGlobalOptions 74*83ee113eSDavid van Moolenbroek GetScopes 75*83ee113eSDavid van Moolenbroek PrintSubnetConfig 76*83ee113eSDavid van Moolenbroek 77*83ee113eSDavid van Moolenbroek In addition, the resulting subnets configuration will have the "deny 78*83ee113eSDavid van Moolenbroek dynamic bootp clients" you should take them out if that's not what you 79*83ee113eSDavid van Moolenbroek want :). 80*83ee113eSDavid van Moolenbroek 81*83ee113eSDavid van Moolenbroek Finally, as the parameter structures implied, it is assumed that you 82*83ee113eSDavid van Moolenbroek want the same zone primary and update key for all zones and that the 83*83ee113eSDavid van Moolenbroek same failover is to be applied to all the pools. Furthermore the 84*83ee113eSDavid van Moolenbroek subnet zones are all assumed to be class C delineated, but if you 85*83ee113eSDavid van Moolenbroek happend to be delegated at the class B level, this will work fine too. 86*83ee113eSDavid van Moolenbroek 87*83ee113eSDavid van MoolenbroekAuthor: Shu-Min Chang <smchang@yahoo.com> 88*83ee113eSDavid van Moolenbroek 89*83ee113eSDavid van MoolenbroekCopyright: Please read the top of the source code 90*83ee113eSDavid van Moolenbroek 91*83ee113eSDavid van MoolenbroekAcknowledgement: 92*83ee113eSDavid van Moolenbroek Brian L. King for coding help, Douglas A. Darrah for testing, and James E. 93*83ee113eSDavid van MoolenbroekPressley for being the DHCP reference book :). 94*83ee113eSDavid van Moolenbroek 95*83ee113eSDavid van MoolenbroekUsage: $ARGV -s <Srv> -o <Out> [-p <Pri> [-k <key>]] [-f <Fo>] 96*83ee113eSDavid van Moolenbroek 97*83ee113eSDavid van MoolenbroekVersion: 1.0.1 98*83ee113eSDavid van Moolenbroek 99*83ee113eSDavid van MoolenbroekENDOFHELP 100*83ee113eSDavid van Moolenbroek 101*83ee113eSDavid van Moolenbroek###################### Begin Main Program #################################### 102*83ee113eSDavid van Moolenbroek 103*83ee113eSDavid van Moolenbroek my (%opts, %GlobalOptions, %SuperScopes, %Scopes); 104*83ee113eSDavid van Moolenbroek 105*83ee113eSDavid van Moolenbroek ### Get parameters and make sure that they meet the require/optoinal criteria 106*83ee113eSDavid van Moolenbroek getopts('s:o:p:k:f:', \%opts) or die $usage; 107*83ee113eSDavid van Moolenbroek ($opts{s} and $opts{o}) or die $usage; 108*83ee113eSDavid van Moolenbroek if ($opts{k}) { $opts{p} or die $usage; } 109*83ee113eSDavid van Moolenbroek 110*83ee113eSDavid van Moolenbroek ### Read all the registry stuff into the memory 111*83ee113eSDavid van Moolenbroek %GlobalOptions = GetGlobalOptions($opts{s}); 112*83ee113eSDavid van Moolenbroek %SuperScopes = GetSuperScope($opts{s}); 113*83ee113eSDavid van Moolenbroek %Scopes = GetScopes ($opts{s}); 114*83ee113eSDavid van Moolenbroek 115*83ee113eSDavid van Moolenbroek ### Process and print out to the output file 116*83ee113eSDavid van Moolenbroek my ($outfile, $i, $j, @Domains); 117*83ee113eSDavid van Moolenbroek 118*83ee113eSDavid van Moolenbroek $outfile = new FileHandle "> $opts{o}"; 119*83ee113eSDavid van Moolenbroek if (!defined $outfile) { 120*83ee113eSDavid van Moolenbroek die "Can't open file: $opts{o}: $!"; 121*83ee113eSDavid van Moolenbroek } 122*83ee113eSDavid van Moolenbroek 123*83ee113eSDavid van Moolenbroek for $i (keys %SuperScopes) { 124*83ee113eSDavid van Moolenbroek print $outfile "\n##############################################################\n"; 125*83ee113eSDavid van Moolenbroek my ($Scopename) = $i; 126*83ee113eSDavid van Moolenbroek $Scopename =~ s/ //g; 127*83ee113eSDavid van Moolenbroek print $outfile "shared-network $Scopename {\n"; 128*83ee113eSDavid van Moolenbroek foreach $j (@{$SuperScopes{$i}}) { 129*83ee113eSDavid van Moolenbroek PrintSubnetConfig($outfile, \%GlobalOptions, \%{$Scopes{$j}}, $j, "\t", $opts{f}); 130*83ee113eSDavid van Moolenbroek InsertIfUnique (\@Domains, $Scopes{$j}{domain}) if exists $Scopes{$j}{domain}; 131*83ee113eSDavid van Moolenbroek delete $Scopes{$j}; 132*83ee113eSDavid van Moolenbroek } 133*83ee113eSDavid van Moolenbroek print $outfile "}\n"; 134*83ee113eSDavid van Moolenbroek if ($opts{p} or $opts{k}) { 135*83ee113eSDavid van Moolenbroek foreach $j (@{$SuperScopes{$i}}) { 136*83ee113eSDavid van Moolenbroek PrintSubnetUpdate($outfile, $j, $opts{p}, $opts{k}); 137*83ee113eSDavid van Moolenbroek } 138*83ee113eSDavid van Moolenbroek } 139*83ee113eSDavid van Moolenbroek } 140*83ee113eSDavid van Moolenbroek 141*83ee113eSDavid van Moolenbroek for $i (keys %Scopes) { 142*83ee113eSDavid van Moolenbroek print $outfile "\n##############################################################\n"; 143*83ee113eSDavid van Moolenbroek PrintSubnetConfig($outfile, \%GlobalOptions, \%{$Scopes{$i}}, $i, "", $opts{f}); 144*83ee113eSDavid van Moolenbroek if ($opts{p} or $opts{k}) { PrintSubnetUpdate($outfile, $i, $opts{p}, $opts{k}); } 145*83ee113eSDavid van Moolenbroek InsertIfUnique (\@Domains, $Scopes{$i}{domain}) if exists $Scopes{$i}{domain}; 146*83ee113eSDavid van Moolenbroek } 147*83ee113eSDavid van Moolenbroek 148*83ee113eSDavid van Moolenbroek if ($opts{p} or $opts{k}) { 149*83ee113eSDavid van Moolenbroek InsertIfUnique (\@Domains, $GlobalOptions{domain}) if exists $GlobalOptions{domain}; 150*83ee113eSDavid van Moolenbroek for $i (@Domains) { 151*83ee113eSDavid van Moolenbroek PrintDomainUpdate($outfile, $i, $opts{p}, $opts{k}); 152*83ee113eSDavid van Moolenbroek } 153*83ee113eSDavid van Moolenbroek } 154*83ee113eSDavid van Moolenbroek 155*83ee113eSDavid van Moolenbroek undef ($outfile); 156*83ee113eSDavid van Moolenbroek print "Done.\n"; 157*83ee113eSDavid van Moolenbroek exit(); 158*83ee113eSDavid van Moolenbroek 159*83ee113eSDavid van Moolenbroek################################## End Main Program ########################### 160*83ee113eSDavid van Moolenbroek 161*83ee113eSDavid van Moolenbroek 162*83ee113eSDavid van Moolenbroek 163*83ee113eSDavid van Moolenbroek 164*83ee113eSDavid van Moolenbroek 165*83ee113eSDavid van Moolenbroek###################################################################### 166*83ee113eSDavid van Moolenbroeksub InsertIfUnique ($$) { 167*83ee113eSDavid van Moolenbroek my ($Array, $data) = @_; 168*83ee113eSDavid van Moolenbroek# purpose: insert $data into array @{$Array} iff the data is not in there yet 169*83ee113eSDavid van Moolenbroek# input: 170*83ee113eSDavid van Moolenbroek# $data: scalar data to be added to the @{$Array} if unique 171*83ee113eSDavid van Moolenbroek# $Array: reference of the Array to compare the uniqueness of the $data 172*83ee113eSDavid van Moolenbroek# output: 173*83ee113eSDavid van Moolenbroek# $Array: reference of the array with the resulting array. 174*83ee113eSDavid van Moolenbroek# return: none 175*83ee113eSDavid van Moolenbroek 176*83ee113eSDavid van Moolenbroek my ($i); 177*83ee113eSDavid van Moolenbroek 178*83ee113eSDavid van Moolenbroek for ($i=0; $i<=$#{$Array} && ${$Array}[$i] ne $data; $i++) { } 179*83ee113eSDavid van Moolenbroek 180*83ee113eSDavid van Moolenbroek if ($i > $#{$Array}) { 181*83ee113eSDavid van Moolenbroek ${$Array}[$i] = $data; 182*83ee113eSDavid van Moolenbroek } 183*83ee113eSDavid van Moolenbroek} 184*83ee113eSDavid van Moolenbroek###################################################################### 185*83ee113eSDavid van Moolenbroeksub PrintDomainUpdate ($$$$) { 186*83ee113eSDavid van Moolenbroek my ($outfile, $Domain, $DDNSServer, $key) = @_; 187*83ee113eSDavid van Moolenbroek# purpose: print out the foward domain zone update declaration 188*83ee113eSDavid van Moolenbroek# input: 189*83ee113eSDavid van Moolenbroek# $outfile: filehandle of the file to write the output to 190*83ee113eSDavid van Moolenbroek# $Domain: a string representing the forward domain 191*83ee113eSDavid van Moolenbroek# $DDNSServer: a string of the DNS server accepting the DDNS update 192*83ee113eSDavid van Moolenbroek# $key: a string representing the key used to update the zone 193*83ee113eSDavid van Moolenbroek# output: none 194*83ee113eSDavid van Moolenbroek# return: none 195*83ee113eSDavid van Moolenbroek# 196*83ee113eSDavid van Moolenbroek 197*83ee113eSDavid van Moolenbroek print $outfile "zone $Domain {\n"; 198*83ee113eSDavid van Moolenbroek print $outfile "\tprimary $DDNSServer;\n"; 199*83ee113eSDavid van Moolenbroek !$key or print $outfile "\tkey $key;\n"; 200*83ee113eSDavid van Moolenbroek print $outfile "}\n"; 201*83ee113eSDavid van Moolenbroek 202*83ee113eSDavid van Moolenbroek} 203*83ee113eSDavid van Moolenbroek###################################################################### 204*83ee113eSDavid van Moolenbroeksub PrintSubnetUpdate ($$$$) { 205*83ee113eSDavid van Moolenbroek my ($outfile, $Subnet, $DDNSServer, $key) = @_; 206*83ee113eSDavid van Moolenbroek# purpose: print out the reverse domain zone update declaration 207*83ee113eSDavid van Moolenbroek# input: 208*83ee113eSDavid van Moolenbroek# $outfile: filehandle of the file to write the output to 209*83ee113eSDavid van Moolenbroek# $Subnet: a string representing the subnet in the form 1.2.3.4 210*83ee113eSDavid van Moolenbroek# $DDNSServer: a string of the DNS server accepting the DDNS update 211*83ee113eSDavid van Moolenbroek# $key: a string representing the key used to update the zone 212*83ee113eSDavid van Moolenbroek# output: none 213*83ee113eSDavid van Moolenbroek# return: none 214*83ee113eSDavid van Moolenbroek# 215*83ee113eSDavid van Moolenbroek 216*83ee113eSDavid van Moolenbroek my ($Reverse); 217*83ee113eSDavid van Moolenbroek 218*83ee113eSDavid van Moolenbroek $_ = join (".", reverse(split(/\./, $Subnet))); 219*83ee113eSDavid van Moolenbroek m/\d*\.(.*)/; 220*83ee113eSDavid van Moolenbroek $Reverse = $1; 221*83ee113eSDavid van Moolenbroek print $outfile "zone $Reverse.in-addr.arpa. {\n"; 222*83ee113eSDavid van Moolenbroek print $outfile "\tprimary $DDNSServer;\n"; 223*83ee113eSDavid van Moolenbroek !$key or print $outfile "\tkey $key;\n"; 224*83ee113eSDavid van Moolenbroek print $outfile "}\n"; 225*83ee113eSDavid van Moolenbroek 226*83ee113eSDavid van Moolenbroek} 227*83ee113eSDavid van Moolenbroek###################################################################### 228*83ee113eSDavid van Moolenbroeksub PrintSubnetConfig ($$$$$$) { 229*83ee113eSDavid van Moolenbroek my ($outfile, $GlobalOptions, $Scope, $Subnet, $prefix, $failover) = @_; 230*83ee113eSDavid van Moolenbroek# purpose: print out the effective scope configuration for one subnet as 231*83ee113eSDavid van Moolenbroek# derived from the global and scope options. 232*83ee113eSDavid van Moolenbroek# input: 233*83ee113eSDavid van Moolenbroek# $outfile: filehandle of the file to write the output to 234*83ee113eSDavid van Moolenbroek# $GlobalOptions: refernce to the hashed variable from GetGlobalOptions 235*83ee113eSDavid van Moolenbroek# $Scopes: reference to the hashed variable of the subnet in interest 236*83ee113eSDavid van Moolenbroek# $Subnet: string variable of the subnet being processed 237*83ee113eSDavid van Moolenbroek# $prefix: string to be printed before each line (designed for tab) 238*83ee113eSDavid van Moolenbroek# $failover: string to be used for the "failover peer" line 239*83ee113eSDavid van Moolenbroek# output: none 240*83ee113eSDavid van Moolenbroek# return: none 241*83ee113eSDavid van Moolenbroek# 242*83ee113eSDavid van Moolenbroek my ($pound) = ( ${$Scope}{disable}? "#".$prefix : $prefix); 243*83ee113eSDavid van Moolenbroek print $outfile $pound, "subnet $Subnet netmask ${$Scope}{mask} {\n"; 244*83ee113eSDavid van Moolenbroek print $outfile "$prefix# Name: ${$Scope}{name}\n"; 245*83ee113eSDavid van Moolenbroek print $outfile "$prefix# Comment: ${$Scope}{comment}\n"; 246*83ee113eSDavid van Moolenbroek if (exists ${$Scope}{routers}) { 247*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption routers @{${$Scope}{routers}};\n"; 248*83ee113eSDavid van Moolenbroek } elsif (exists ${$GlobalOptions}{routers}) { 249*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption routers @{${$GlobalOptions}{routers}};\t# NOTE: obtained from global option, bad practice detected\n"; 250*83ee113eSDavid van Moolenbroek } else { 251*83ee113eSDavid van Moolenbroek print $outfile "### WARNING: No router was found for this subnet!!! ##########\n"; 252*83ee113eSDavid van Moolenbroek } 253*83ee113eSDavid van Moolenbroek 254*83ee113eSDavid van Moolenbroek if (exists ${$Scope}{dnses}) { 255*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption domain-name-servers ", join(",", @{${$Scope}{dnses}}), ";\n"; 256*83ee113eSDavid van Moolenbroek } elsif (exists ${$GlobalOptions}{dnses}) { 257*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption domain-name-servers ", join(",", @{${$GlobalOptions}{dnses}}), ";\n"; 258*83ee113eSDavid van Moolenbroek } 259*83ee113eSDavid van Moolenbroek 260*83ee113eSDavid van Moolenbroek if (exists ${$Scope}{domain}) { 261*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption domain-name \"${$Scope}{domain}\";\n"; 262*83ee113eSDavid van Moolenbroek } elsif (exists ${$GlobalOptions}{domain}) { 263*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption domain-name \"${$GlobalOptions}{domain}\";\n"; 264*83ee113eSDavid van Moolenbroek } 265*83ee113eSDavid van Moolenbroek 266*83ee113eSDavid van Moolenbroek if (exists ${$Scope}{broadcast}) { 267*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption broadcast-address ${$Scope}{broadcast};\n"; 268*83ee113eSDavid van Moolenbroek } elsif (exists ${$GlobalOptions}{broadcast}) { 269*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption broadcast-address ${$GlobalOptions}{broadcast};\n"; 270*83ee113eSDavid van Moolenbroek } 271*83ee113eSDavid van Moolenbroek 272*83ee113eSDavid van Moolenbroek if (exists ${$Scope}{winses}) { 273*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption netbios-name-servers ", join(",", @{${$Scope}{winses}}), ";\n"; 274*83ee113eSDavid van Moolenbroek } elsif (exists ${$GlobalOptions}{winses}) { 275*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption netbios-name-servers ", join(",", @{${$GlobalOptions}{winses}}), ";\n"; 276*83ee113eSDavid van Moolenbroek } 277*83ee113eSDavid van Moolenbroek 278*83ee113eSDavid van Moolenbroek if (exists ${$Scope}{winstype}) { 279*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption netbios-node-type ${$Scope}{winstype};\n"; 280*83ee113eSDavid van Moolenbroek } elsif (exists ${$GlobalOptions}{winstype}) { 281*83ee113eSDavid van Moolenbroek print $outfile $pound, "\toption netbios-node-type ${$GlobalOptions}{winstype};\n" 282*83ee113eSDavid van Moolenbroek } 283*83ee113eSDavid van Moolenbroek 284*83ee113eSDavid van Moolenbroek print $outfile $pound, "\tdefault-lease-time ${$Scope}{leaseduration};\n"; 285*83ee113eSDavid van Moolenbroek print $outfile $pound, "\tpool {\n"; 286*83ee113eSDavid van Moolenbroek for (my $r=0; $r<=$#{${$Scope}{ranges}}; $r+=2) { 287*83ee113eSDavid van Moolenbroek print $outfile $pound, "\t\trange ${$Scope}{ranges}[$r] ${$Scope}{ranges}[$r+1];\n"; 288*83ee113eSDavid van Moolenbroek } 289*83ee113eSDavid van Moolenbroek !$failover or print $outfile $pound, "\t\tfailover peer \"$failover\";\n"; 290*83ee113eSDavid van Moolenbroek print $outfile $pound, "\t\tdeny dynamic bootp clients;\n"; 291*83ee113eSDavid van Moolenbroek print $outfile $pound, "\t}\n"; 292*83ee113eSDavid van Moolenbroek print $outfile $pound, "}\n"; 293*83ee113eSDavid van Moolenbroek} 294*83ee113eSDavid van Moolenbroek 295*83ee113eSDavid van Moolenbroek###################################################################### 296*83ee113eSDavid van Moolenbroeksub GetScopes ($) { 297*83ee113eSDavid van Moolenbroek my ($Server) = @_; 298*83ee113eSDavid van Moolenbroek my (%Scopes); 299*83ee113eSDavid van Moolenbroek# purpose: to return NT4 server's scope configuration 300*83ee113eSDavid van Moolenbroek# input: 301*83ee113eSDavid van Moolenbroek# $Server: string of the valid IP or name of the NT4 server 302*83ee113eSDavid van Moolenbroek# output: none 303*83ee113eSDavid van Moolenbroek# return: 304*83ee113eSDavid van Moolenbroek# %Scope: hash of hash of hash of various data types to be returned of the 305*83ee113eSDavid van Moolenbroek# following data structure 306*83ee113eSDavid van Moolenbroek# $Scope{<subnet>}{disable} => boolean 307*83ee113eSDavid van Moolenbroek# $Scope{<subnet>}{mask} => string (e.g. "1.2.3.255") 308*83ee113eSDavid van Moolenbroek# $Scope{<subnet>}{name} => string (e.g "Office Subnet #1") 309*83ee113eSDavid van Moolenbroek# $Scope{<subnet>}{comment} => string (e.g. "This is a funny subnet") 310*83ee113eSDavid van Moolenbroek# $Scope{<subnet>}{ranges} => array of paired inclusion IP addresses 311*83ee113eSDavid van Moolenbroek# (e.g. "1.2.3.1 1.2.3.10 1.2.3.100 10.2.3.200 312*83ee113eSDavid van Moolenbroek# says that we have 2 inclusion ranges of 313*83ee113eSDavid van Moolenbroek# 1-10 and 100-200) 314*83ee113eSDavid van Moolenbroek# $Scopes{<subnet>}{routers} => array of IP address strings 315*83ee113eSDavid van Moolenbroek# $Scopes{<subnet>}{dnses} => array of IP address/name string 316*83ee113eSDavid van Moolenbroek# $Scopes{<subnet>}{domain} > string 317*83ee113eSDavid van Moolenbroek# $Scopes{<subnet>}{broadcast} => string 318*83ee113eSDavid van Moolenbroek# $Scopes{<subnet>}{winses} => array of IP addresses/name string 319*83ee113eSDavid van Moolenbroek# $Scopes{<subnet>}{winstype} => integer 320*83ee113eSDavid van Moolenbroek# $Scopes{<subnet>}{leaseduration} => integer 321*83ee113eSDavid van Moolenbroek 322*83ee113eSDavid van Moolenbroek my ($RegVal, @Subnets, @Router, $SubnetName, $SubnetComment, @SubnetOptions, @SRouter, @SDNSServers, @SDomainname, @SWINSservers, @SNetBIOS, @SLeaseDuration, @SSubnetState, @SExclusionRanges, @SSubnetAddress, @SSubnetMask, @SFirstAddress, $SStartAddress, $SEndAddress, @InclusionRanges, @SBroadcastAddress); 323*83ee113eSDavid van Moolenbroek 324*83ee113eSDavid van Moolenbroek print "Getting list of subnets\n"; 325*83ee113eSDavid van Moolenbroek if (Registry::GetRegSubkeyList ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets", \@Subnets)) { 326*83ee113eSDavid van Moolenbroek die "Unable to obtain a list of subnets from the server!\n"; 327*83ee113eSDavid van Moolenbroek } 328*83ee113eSDavid van Moolenbroek 329*83ee113eSDavid van Moolenbroek for (my $i=0; $i<=$#Subnets; $i++) { 330*83ee113eSDavid van Moolenbroek print "\t Fetching Subnet $Subnets[$i] (",$i+1, "/", $#Subnets+1, "): "; 331*83ee113eSDavid van Moolenbroek 332*83ee113eSDavid van Moolenbroek print "."; 333*83ee113eSDavid van Moolenbroek if (!Registry::GetRegSubkeyList ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\IpRanges", \@SFirstAddress)) { 334*83ee113eSDavid van Moolenbroek # Don't know why MS has a tree for this, but as far 335*83ee113eSDavid van Moolenbroek # as I can tell, only one subtree will ever come out of 336*83ee113eSDavid van Moolenbroek # this, so I'm skipping the 'for' loop 337*83ee113eSDavid van Moolenbroek 338*83ee113eSDavid van Moolenbroek print "."; 339*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\IpRanges\\$SFirstAddress[0]\\StartAddress", \$RegVal)) { 340*83ee113eSDavid van Moolenbroek $SStartAddress = $RegVal; 341*83ee113eSDavid van Moolenbroek } 342*83ee113eSDavid van Moolenbroek print "."; 343*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\IpRanges\\$SFirstAddress[0]\\EndAddress", \$RegVal)) { 344*83ee113eSDavid van Moolenbroek $SEndAddress = $RegVal; 345*83ee113eSDavid van Moolenbroek } 346*83ee113eSDavid van Moolenbroek# print "\n\tInclusion Range: ", Registry::ExtractIp($SStartAddress), " - ", Registry::ExtractIp($SEndAddress),"\n"; 347*83ee113eSDavid van Moolenbroek 348*83ee113eSDavid van Moolenbroek } else { 349*83ee113eSDavid van Moolenbroek die "\n\n# Error Getting Inclusion Range FirstAddress!!!\n\n"; 350*83ee113eSDavid van Moolenbroek } 351*83ee113eSDavid van Moolenbroek 352*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\ExcludedIpRanges", \$RegVal)) { 353*83ee113eSDavid van Moolenbroek @SExclusionRanges = Registry::ExtractExclusionRanges($RegVal); 354*83ee113eSDavid van Moolenbroek 355*83ee113eSDavid van Moolenbroek# for (my $j=2; $j<=$#SExclusionRanges; $j+=2) { 356*83ee113eSDavid van Moolenbroek# if (unpack("L",$SExclusionRanges[$j]) < unpack("L",$SExclusionRanges[$j-2])) { 357*83ee113eSDavid van Moolenbroek# print ("\n******** Subnet exclusion ranges out of order ********\n"); 358*83ee113eSDavid van Moolenbroek# } 359*83ee113eSDavid van Moolenbroek# } 360*83ee113eSDavid van Moolenbroek 361*83ee113eSDavid van Moolenbroek @SExclusionRanges = sort(@SExclusionRanges); 362*83ee113eSDavid van Moolenbroek 363*83ee113eSDavid van Moolenbroek# print "\n\tExclusion Ranges: "; 364*83ee113eSDavid van Moolenbroek# for (my $j=0; $j<=$#SExclusionRanges; $j+=2) { 365*83ee113eSDavid van Moolenbroek# print "\n\t\t",Registry::ExtractIp($SExclusionRanges[$j])," - ",Registry::ExtractIp($SExclusionRanges[$j+1]); 366*83ee113eSDavid van Moolenbroek# } 367*83ee113eSDavid van Moolenbroek 368*83ee113eSDavid van Moolenbroek } 369*83ee113eSDavid van Moolenbroek @InclusionRanges = FindInclusionRanges ($SStartAddress, $SEndAddress, @SExclusionRanges); 370*83ee113eSDavid van Moolenbroek 371*83ee113eSDavid van Moolenbroek print "."; 372*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\SubnetName", \$RegVal)) { 373*83ee113eSDavid van Moolenbroek $SubnetName = $RegVal; 374*83ee113eSDavid van Moolenbroek# print "\n\tSubnetName: $SubnetName"; 375*83ee113eSDavid van Moolenbroek } 376*83ee113eSDavid van Moolenbroek 377*83ee113eSDavid van Moolenbroek print "."; 378*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\SubnetComment", \$RegVal)) { 379*83ee113eSDavid van Moolenbroek $SubnetComment = $RegVal; 380*83ee113eSDavid van Moolenbroek# print "\n\tSubnetComment: $SubnetComment"; 381*83ee113eSDavid van Moolenbroek } 382*83ee113eSDavid van Moolenbroek print "."; 383*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\SubnetAddress", \$RegVal)) { 384*83ee113eSDavid van Moolenbroek @SSubnetAddress = Registry::ExtractIp($RegVal); 385*83ee113eSDavid van Moolenbroek# print "\n\tSubnetAddress: $SSubnetAddress[0]"; 386*83ee113eSDavid van Moolenbroek } 387*83ee113eSDavid van Moolenbroek print "."; 388*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\SubnetMask", \$RegVal)) { 389*83ee113eSDavid van Moolenbroek @SSubnetMask = Registry::ExtractIp($RegVal); 390*83ee113eSDavid van Moolenbroek# print "\n\tSubnetMask: $SSubnetMask[0]"; 391*83ee113eSDavid van Moolenbroek } 392*83ee113eSDavid van Moolenbroek 393*83ee113eSDavid van Moolenbroek print "."; 394*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\SubnetState", \$RegVal)) { 395*83ee113eSDavid van Moolenbroek @SSubnetState = Registry::ExtractHex ($RegVal); 396*83ee113eSDavid van Moolenbroek# print "\n\tSubnetState = $SSubnetState[0]"; 397*83ee113eSDavid van Moolenbroek } 398*83ee113eSDavid van Moolenbroek 399*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{disable} = hex($SSubnetState[0]) ? 1 : 0; 400*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{mask} = $SSubnetMask[0]; 401*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{name} = $SubnetName; 402*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{comment} = $SubnetComment; 403*83ee113eSDavid van Moolenbroek for (my $r=0; $r<=$#InclusionRanges; $r++) { 404*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{ranges}[$r] = Registry::ExtractIp($InclusionRanges[$r]); 405*83ee113eSDavid van Moolenbroek } 406*83ee113eSDavid van Moolenbroek 407*83ee113eSDavid van Moolenbroek################## Get scope options 408*83ee113eSDavid van Moolenbroek 409*83ee113eSDavid van Moolenbroek my (@SubnetOptionsList); 410*83ee113eSDavid van Moolenbroek 411*83ee113eSDavid van Moolenbroek print "\n\t\tOptions:"; 412*83ee113eSDavid van Moolenbroek if (Registry::GetRegSubkeyList ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\SubnetOptions", \@SubnetOptionsList)) { 413*83ee113eSDavid van Moolenbroek die "Unable to get subnet options list for $Subnets[$i]!\n"; 414*83ee113eSDavid van Moolenbroek } 415*83ee113eSDavid van Moolenbroek 416*83ee113eSDavid van Moolenbroek for (my $j=0; $j<=$#SubnetOptionsList; $j++) { 417*83ee113eSDavid van Moolenbroek print "."; 418*83ee113eSDavid van Moolenbroek if (!Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\Subnets\\$Subnets[$i]\\SubnetOptions\\$SubnetOptionsList[$j]\\OptionValue", \$RegVal)) { 419*83ee113eSDavid van Moolenbroek for ($SubnetOptionsList[$j]) { 420*83ee113eSDavid van Moolenbroek /003/ and do { 421*83ee113eSDavid van Moolenbroek# @SRouter = Registry::ExtractOptionIps($RegVal); 422*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{routers} = [Registry::ExtractOptionIps($RegVal)]; 423*83ee113eSDavid van Moolenbroek last; 424*83ee113eSDavid van Moolenbroek }; 425*83ee113eSDavid van Moolenbroek /006/ and do { 426*83ee113eSDavid van Moolenbroek @SDNSServers = Registry::ExtractOptionIps($RegVal); 427*83ee113eSDavid van Moolenbroek for (my $d=0; $d<=$#SDNSServers; $d++) { 428*83ee113eSDavid van Moolenbroek my ($ipname, $rest) = gethostbyaddr(pack("C4", split(/\./, $SDNSServers[$d])), &AF_INET); 429*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{dnses}[$d] = $ipname ? $ipname : $SDNSServers[$d]; 430*83ee113eSDavid van Moolenbroek } 431*83ee113eSDavid van Moolenbroek last; 432*83ee113eSDavid van Moolenbroek }; 433*83ee113eSDavid van Moolenbroek /015/ and do { 434*83ee113eSDavid van Moolenbroek @SDomainname = Registry::ExtractOptionStrings($RegVal); 435*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{domain} = $SDomainname[0]; 436*83ee113eSDavid van Moolenbroek last; 437*83ee113eSDavid van Moolenbroek }; 438*83ee113eSDavid van Moolenbroek /028/ and do { 439*83ee113eSDavid van Moolenbroek @SBroadcastAddress = Registry::ExtractOptionIps($RegVal); 440*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{broadcast} = $SBroadcastAddress[0]; 441*83ee113eSDavid van Moolenbroek last; 442*83ee113eSDavid van Moolenbroek }; 443*83ee113eSDavid van Moolenbroek /044/ and do { 444*83ee113eSDavid van Moolenbroek @SWINSservers = Registry::ExtractOptionIps($RegVal); 445*83ee113eSDavid van Moolenbroek for (my $w=0; $w<=$#SWINSservers; $w++) { 446*83ee113eSDavid van Moolenbroek my ($ipname, $rest) = gethostbyaddr(pack("C4", split(/\./, $SWINSservers[$w])), &AF_INET); 447*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{winses}[$w] = $ipname ? $ipname : $SWINSservers[$w]; 448*83ee113eSDavid van Moolenbroek } 449*83ee113eSDavid van Moolenbroek last; 450*83ee113eSDavid van Moolenbroek }; 451*83ee113eSDavid van Moolenbroek /046/ and do { 452*83ee113eSDavid van Moolenbroek @SNetBIOS = Registry::ExtractOptionHex($RegVal); 453*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{winstype} = hex($SNetBIOS[0]); 454*83ee113eSDavid van Moolenbroek last; 455*83ee113eSDavid van Moolenbroek }; 456*83ee113eSDavid van Moolenbroek /051/ and do { 457*83ee113eSDavid van Moolenbroek @SLeaseDuration = Registry::ExtractOptionHex($RegVal); 458*83ee113eSDavid van Moolenbroek $Scopes{$Subnets[$i]}{leaseduration} = hex($SLeaseDuration[0]); 459*83ee113eSDavid van Moolenbroek last; 460*83ee113eSDavid van Moolenbroek }; 461*83ee113eSDavid van Moolenbroek die "This program does not recognize subnet option \#$SubnetOptionsList[$j] yet!\n" 462*83ee113eSDavid van Moolenbroek } 463*83ee113eSDavid van Moolenbroek } else { 464*83ee113eSDavid van Moolenbroek die "Unable to obtain option SubnetOptionsList[$j] from $Subnets[$i], most likely a registry problem!\n" 465*83ee113eSDavid van Moolenbroek } 466*83ee113eSDavid van Moolenbroek } 467*83ee113eSDavid van Moolenbroek print "\n"; 468*83ee113eSDavid van Moolenbroek } 469*83ee113eSDavid van Moolenbroek 470*83ee113eSDavid van Moolenbroek return %Scopes; 471*83ee113eSDavid van Moolenbroek} 472*83ee113eSDavid van Moolenbroek 473*83ee113eSDavid van Moolenbroek###################################################################### 474*83ee113eSDavid van Moolenbroeksub FindInclusionRanges ($$@) { 475*83ee113eSDavid van Moolenbroek my ($StartAddress, $EndAddress, @ExclusionRanges) = @_; 476*83ee113eSDavid van Moolenbroek# Purpose: to calculate and return the DHCP inclusion ranges out of 477*83ee113eSDavid van Moolenbroek# data provided by the NT4 DHCP server 478*83ee113eSDavid van Moolenbroek# input: $StartAddress: 479*83ee113eSDavid van Moolenbroek# $EndAddress: 480*83ee113eSDavid van Moolenbroek# @ExclusionRanges 481*83ee113eSDavid van Moolenbroek# output: none 482*83ee113eSDavid van Moolenbroek# return: An arry of IP address pair representing the inclusion ranges 483*83ee113eSDavid van Moolenbroek# in the native registry format. 484*83ee113eSDavid van Moolenbroek# 485*83ee113eSDavid van Moolenbroek 486*83ee113eSDavid van Moolenbroek my ($SA, $EA, @ER); 487*83ee113eSDavid van Moolenbroek $SA = unpack("L", $StartAddress); 488*83ee113eSDavid van Moolenbroek $EA = unpack("L", $EndAddress); 489*83ee113eSDavid van Moolenbroek @ER = @ExclusionRanges; 490*83ee113eSDavid van Moolenbroek for (my $i=0; $i<=$#ER; $i++) { 491*83ee113eSDavid van Moolenbroek $ER[$i] = unpack ("L", $ER[$i]); 492*83ee113eSDavid van Moolenbroek } 493*83ee113eSDavid van Moolenbroek 494*83ee113eSDavid van Moolenbroek my @InclusionRanges; 495*83ee113eSDavid van Moolenbroek 496*83ee113eSDavid van Moolenbroek 497*83ee113eSDavid van Moolenbroek $InclusionRanges[0] = $SA; 498*83ee113eSDavid van Moolenbroek $InclusionRanges[1] = $EA; 499*83ee113eSDavid van Moolenbroek 500*83ee113eSDavid van Moolenbroek for (my $i=0; $i<=$#ER; $i+=2) { 501*83ee113eSDavid van Moolenbroek if ($ER[$i] == $InclusionRanges[$#InclusionRanges-1]) { 502*83ee113eSDavid van Moolenbroek $InclusionRanges[$#InclusionRanges-1] = $ER[$i+1] + 1; 503*83ee113eSDavid van Moolenbroek } 504*83ee113eSDavid van Moolenbroek if ($ER[$i] > $InclusionRanges[$#InclusionRanges-1]) { 505*83ee113eSDavid van Moolenbroek $InclusionRanges[$#InclusionRanges] = $ER[$i]-1; 506*83ee113eSDavid van Moolenbroek } 507*83ee113eSDavid van Moolenbroek if (($ER[$i+1] > $InclusionRanges[$#InclusionRanges]) && 508*83ee113eSDavid van Moolenbroek ($ER[$i+1] != $EA)) { 509*83ee113eSDavid van Moolenbroek $InclusionRanges[$#InclusionRanges+1] = $ER[$i+1] + 1; 510*83ee113eSDavid van Moolenbroek $InclusionRanges[$#InclusionRanges+1] = $EA; 511*83ee113eSDavid van Moolenbroek } 512*83ee113eSDavid van Moolenbroek if ($InclusionRanges[$#InclusionRanges] < $InclusionRanges[$#InclusionRanges-1]) { 513*83ee113eSDavid van Moolenbroek $#InclusionRanges -= 2; 514*83ee113eSDavid van Moolenbroek } 515*83ee113eSDavid van Moolenbroek } 516*83ee113eSDavid van Moolenbroek 517*83ee113eSDavid van Moolenbroek for (my $i=0; $i<=$#InclusionRanges; $i++) { 518*83ee113eSDavid van Moolenbroek $InclusionRanges[$i] = pack("L", $InclusionRanges[$i]); 519*83ee113eSDavid van Moolenbroek # print "Inclusion: ", Registry::ExtractIp($InclusionRanges[$i]), "\n"; 520*83ee113eSDavid van Moolenbroek } 521*83ee113eSDavid van Moolenbroek return @InclusionRanges; 522*83ee113eSDavid van Moolenbroek} 523*83ee113eSDavid van Moolenbroek 524*83ee113eSDavid van Moolenbroek#################################################################### 525*83ee113eSDavid van Moolenbroeksub GetSuperScope ($) { 526*83ee113eSDavid van Moolenbroek my ($Server) = @_; 527*83ee113eSDavid van Moolenbroek my (%SuperScopes); 528*83ee113eSDavid van Moolenbroek# 529*83ee113eSDavid van Moolenbroek# purpose: gets the Superscope list from the given server 530*83ee113eSDavid van Moolenbroek# input: 531*83ee113eSDavid van Moolenbroek# $Server: string of the valid IP address or name of the NT4 server 532*83ee113eSDavid van Moolenbroek# ouput: none 533*83ee113eSDavid van Moolenbroek# return: 534*83ee113eSDavid van Moolenbroek# %SuperScopes: hash of array subnets with the following data structure 535*83ee113eSDavid van Moolenbroek# $SuperScopes{<SuperscopeName>} => array of sunbets 536*83ee113eSDavid van Moolenbroek# 537*83ee113eSDavid van Moolenbroek my (@SuperScopeNames, @SCSubnetList); 538*83ee113eSDavid van Moolenbroek 539*83ee113eSDavid van Moolenbroek print "Getting Superscope list: "; 540*83ee113eSDavid van Moolenbroek if (!Registry::GetRegSubkeyList ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\SuperScope", \@SuperScopeNames)) { 541*83ee113eSDavid van Moolenbroek for (my $i=0; $i<=$#SuperScopeNames; $i++) { 542*83ee113eSDavid van Moolenbroek print "."; 543*83ee113eSDavid van Moolenbroek if (!Registry::GetRegSubkeyList ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\SuperScope\\$SuperScopeNames[$i]", \@SCSubnetList)) { 544*83ee113eSDavid van Moolenbroek $SuperScopes{$SuperScopeNames[$i]} = [@SCSubnetList]; 545*83ee113eSDavid van Moolenbroek } 546*83ee113eSDavid van Moolenbroek } 547*83ee113eSDavid van Moolenbroek print "\n"; 548*83ee113eSDavid van Moolenbroek } 549*83ee113eSDavid van Moolenbroek 550*83ee113eSDavid van Moolenbroek return %SuperScopes; 551*83ee113eSDavid van Moolenbroek} 552*83ee113eSDavid van Moolenbroek 553*83ee113eSDavid van Moolenbroek#################################################################### 554*83ee113eSDavid van Moolenbroeksub GetGlobalOptions($) { 555*83ee113eSDavid van Moolenbroek my ($Server) = @_; 556*83ee113eSDavid van Moolenbroek my (%GlobalOptions); 557*83ee113eSDavid van Moolenbroek# purpose: to return NT4 server's global scope configuration 558*83ee113eSDavid van Moolenbroek# input: 559*83ee113eSDavid van Moolenbroek# $Server: string of the valid IP or name of the NT4 server 560*83ee113eSDavid van Moolenbroek# output: none 561*83ee113eSDavid van Moolenbroek# return: 562*83ee113eSDavid van Moolenbroek# %GlobalOptions: hash of hash of various data types to be returned of the 563*83ee113eSDavid van Moolenbroek# following data structure 564*83ee113eSDavid van Moolenbroek# $GlobalOptions{routers} => array of IP address strings 565*83ee113eSDavid van Moolenbroek# $GlobalOptions{dnses} => array of IP address/name string 566*83ee113eSDavid van Moolenbroek# $GlobalOptions{domain} > string 567*83ee113eSDavid van Moolenbroek# $GlobalOptions{broadcast} => string 568*83ee113eSDavid van Moolenbroek# $GlobalOptions{winses} => array of IP addresses/name string 569*83ee113eSDavid van Moolenbroek# $GlobalOptions{winstype} => integer 570*83ee113eSDavid van Moolenbroek 571*83ee113eSDavid van Moolenbroek my ($RegVal, @temp, @GlobalOptionValues); 572*83ee113eSDavid van Moolenbroek 573*83ee113eSDavid van Moolenbroek print "Getting Global Options: "; 574*83ee113eSDavid van Moolenbroek if (Registry::GetRegSubkeyList ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\Configuration\\GlobalOptionValues", \@GlobalOptionValues)) { 575*83ee113eSDavid van Moolenbroek die "Unable to obtain GlobalOptionValues"; 576*83ee113eSDavid van Moolenbroek } 577*83ee113eSDavid van Moolenbroek 578*83ee113eSDavid van Moolenbroek for (my $i=0; $i<=$#GlobalOptionValues; $i++) { 579*83ee113eSDavid van Moolenbroek print "."; 580*83ee113eSDavid van Moolenbroek if (Registry::GetRegKeyVal ("\\\\$Server\\HKEY_LOCAL_MACHINE\\SYSTEM\\CurrentControlSet\\Services\\DHCPServer\\configuration\\globaloptionvalues\\$GlobalOptionValues[$i]\\optionvalue", \$RegVal)) { 581*83ee113eSDavid van Moolenbroek die "Unable to retrive global option $GlobalOptionValues[$i]\n"; 582*83ee113eSDavid van Moolenbroek } 583*83ee113eSDavid van Moolenbroek 584*83ee113eSDavid van Moolenbroek 585*83ee113eSDavid van Moolenbroek for ($GlobalOptionValues[$i]) { 586*83ee113eSDavid van Moolenbroek /003/ and do { 587*83ee113eSDavid van Moolenbroek @temp=Registry::ExtractOptionIps($RegVal); 588*83ee113eSDavid van Moolenbroek $GlobalOptions{routers} = [@temp]; 589*83ee113eSDavid van Moolenbroek last; 590*83ee113eSDavid van Moolenbroek }; 591*83ee113eSDavid van Moolenbroek /006/ and do { 592*83ee113eSDavid van Moolenbroek # DNS Servers 593*83ee113eSDavid van Moolenbroek @temp = Registry::ExtractOptionIps($RegVal); 594*83ee113eSDavid van Moolenbroek for (my $d=0; $d<=$#temp; $d++) { 595*83ee113eSDavid van Moolenbroek my ($ipname, $rest) = gethostbyaddr(pack("C4", split(/\./, $temp[$d])), &AF_INET); 596*83ee113eSDavid van Moolenbroek $GlobalOptions{dnses}[$d] = $ipname ? $ipname : $temp[$d]; 597*83ee113eSDavid van Moolenbroek } 598*83ee113eSDavid van Moolenbroek last; 599*83ee113eSDavid van Moolenbroek }; 600*83ee113eSDavid van Moolenbroek /015/ and do { 601*83ee113eSDavid van Moolenbroek # Domain Name 602*83ee113eSDavid van Moolenbroek @temp = Registry::ExtractOptionStrings($RegVal); 603*83ee113eSDavid van Moolenbroek $GlobalOptions{domain} = $temp[0]; 604*83ee113eSDavid van Moolenbroek last; 605*83ee113eSDavid van Moolenbroek }; 606*83ee113eSDavid van Moolenbroek /028/ and do { 607*83ee113eSDavid van Moolenbroek # broadcast address 608*83ee113eSDavid van Moolenbroek @temp = Registry::ExtractOptionIps($RegVal); 609*83ee113eSDavid van Moolenbroek $GlobalOptions{broadcast} = $temp[0]; 610*83ee113eSDavid van Moolenbroek last; 611*83ee113eSDavid van Moolenbroek }; 612*83ee113eSDavid van Moolenbroek /044/ and do { 613*83ee113eSDavid van Moolenbroek # WINS Servers 614*83ee113eSDavid van Moolenbroek @temp = Registry::ExtractOptionIps ($RegVal); 615*83ee113eSDavid van Moolenbroek $GlobalOptions{winses} = [@temp]; 616*83ee113eSDavid van Moolenbroek for (my $w=0; $w<=$#temp; $w++) { 617*83ee113eSDavid van Moolenbroek my ($ipname, $rest) = gethostbyaddr(pack("C4", split(/\./, $temp[$w])), &AF_INET); 618*83ee113eSDavid van Moolenbroek $GlobalOptions{winses}[$w] = $ipname ? $ipname : $temp[$w]; 619*83ee113eSDavid van Moolenbroek } 620*83ee113eSDavid van Moolenbroek last; 621*83ee113eSDavid van Moolenbroek }; 622*83ee113eSDavid van Moolenbroek /046/ and do { 623*83ee113eSDavid van Moolenbroek # NETBIOS node type 624*83ee113eSDavid van Moolenbroek @temp = Registry::ExtractOptionHex($RegVal); 625*83ee113eSDavid van Moolenbroek $GlobalOptions{winstype} = hex($temp[0]); 626*83ee113eSDavid van Moolenbroek last; 627*83ee113eSDavid van Moolenbroek }; 628*83ee113eSDavid van Moolenbroek die "This program does not recgonize global option \#$GlobalOptionValues[$i] yet!\n" 629*83ee113eSDavid van Moolenbroek } 630*83ee113eSDavid van Moolenbroek } 631*83ee113eSDavid van Moolenbroek print "\n"; 632*83ee113eSDavid van Moolenbroek 633*83ee113eSDavid van Moolenbroek return %GlobalOptions; 634*83ee113eSDavid van Moolenbroek} 635