#!/usr/bin/perl -w use strict; use Getopt::Long; use vars qw($opt_V $opt_h $opt_i $opt_o $verbose $infile $outfile @inputfile $domainname $scope $numOfScopes $netmask $PROGNAME @netlist @elencomac @temp); $PROGNAME = $0; sub print_help (); sub print_usage (); # Some initializations... $opt_o=""; $opt_i=""; @temp= ("", "", "", "", ""); # -------------------------------------------------------------------- # Data input reading and check # -------------------------------------------------------------------- Getopt::Long::Configure('bundling'); GetOptions ("V" => \$opt_V, "version" => \$opt_V, "h" => \$opt_h, "help" => \$opt_h, "i=s" => \$opt_i, "InputFile=s" => \$opt_i, "o=s" => \$opt_o, "OutputFile=s" => \$opt_o); if (($opt_V) || ($opt_h) || ("$opt_o " eq " ") || ("$opt_i " eq " ")) { &print_help(); &print_usage(); exit 1; } ($opt_i) || ($opt_i = shift) || ($opt_i = "/tmp/dhcpd.conf.foobar"); $infile = $1 if ($opt_i =~ /([0-9\-\/a-zA-Z\.]+)/); ($opt_o) || ($opt_o = shift) || ($opt_i = "/tmp/dhcpd.temp"); $outfile = $1 if ($opt_o =~ /([0-9\-\/a-zA-Z\.]+)/); my ($sec,$min,$hour,$mday,$mon,$year,$wday, $yday,$isdst)=localtime(time); # -------------------------------------------------------------------- # Reading Micro$oft cfg file # -------------------------------------------------------------------- open(INFILE,"<$infile") || die("Cannot open $infile: $!\n"); while () { push(@inputfile, $_); } close(INFILE); # -------------------------------------------------------------------- # Opening output file # -------------------------------------------------------------------- open(OUTFILE,">$outfile") || die("Cannot open $outfile: $!\n"); @temp = &rowfind('Dhcp Server ([0-9\.]*) Set DatabaseName "(.*)"'); print OUTFILE "# DHCP Server configuration exported by $PROGNAME "; printf OUTFILE " at %4d-%02d-%02d %02d:%02d:%02d\n#\n", $year+1900,$mon+1,$mday,$hour,$min,$sec; print OUTFILE "# Server IP Address: $temp[0]\n"; # Ugly trick to remind me the $temp[1] value later... $min=$temp[1]; @temp = &rowfind('Dhcp Server ([0-9\.]*) Set DatabasePath "(.*)"'); print OUTFILE "# Configuration exported from: $temp[1]\\$min\n\n"; # ----- Main parameters @temp = &rowfind('Dhcp Server ([0-9\.]*) add scope ([0-9\.]*) ([0-9\.]*) "([a-zA-Z0-9\ ]*)"'); my $serverip=$temp[0]; my $scope=$temp[1]; my $netmask=$temp[2]; my $descrizione=$temp[3]; print OUTFILE "ddns-update-style interim;\n"; print OUTFILE "ignore client-updates;\n\n"; # -------------------------------------------------------------------- # Reading "add scope" added subnets @netlist = `grep -i "add scope" $infile|grep "^Dhcp Server"|sed -e "s/^.*add scope//"|sed -e "s/255.255.*//"|sed -e "s/ //g"`; $numOfScopes = $#netlist+1; print " $numOfScopes subnets found.\n"; if ($numOfScopes > 1) { print OUTFILE "shared-network $infile {\n\n"; } # ----- Lease @temp = &rowfind('Dhcp Server ([0-9\.]*) Add Optiondef ([0-9]*) "Lease" DWORD'); @temp = &rowfind("Dhcp Server ([0-9\.]*) Scope ([0-9\.]*) set optionvalue $temp[1] DWORD ([0-9\"]*)"); print OUTFILE " option default-lease-time ". &cleanstring($temp[2])/2 . ";\n"; print OUTFILE " option max-lease-time ". &cleanstring($temp[2]) . ";\n\n"; # ----- Domain Name @temp = &rowfind('Dhcp Server ([0-9\.]*) Add Optiondef ([0-9]*) "Nome dominio DNS" STRING'); @temp = &rowfind("Dhcp Server ([0-9\.]*) Scope ([0-9\.]*) set optionvalue $temp[1] STRING ([a-zA-Z\-0-9\.\"]*)"); $domainname=&cleanstring($temp[2]); foreach $scope (@netlist) { $scope=&cleanstring($scope); print $scope; # ----- Main parameters my $trg = 'Dhcp Server ([0-9\.]*) add scope ' . $scope . ' ([0-9\.]*) "([a-zA-Z0-9\ ]*)"'; print ">>>$trg<<<\n"; @temp = &rowfind($trg); my $serverip=$temp[0]; my $netmask=$temp[1]; my $descrizione=$temp[2]; print OUTFILE " subnet $scope netmask $netmask { # $descrizione\n"; # ----- Routers @temp = &rowfind('Dhcp Server ([0-9\.]*) Add Optiondef ([0-9]*) "Router"'); $trg = 'Dhcp Server ([0-9\.]*) Scope ' . $scope . ' set optionvalue ' . $temp[1] . ' IPADDRESS ([0-9\.\ \"]*)'; print ">>>$trg<<<\n"; @temp = &rowfind($trg); print OUTFILE " option routers ". &cleanstring($temp[1]) . ";\n"; print OUTFILE " option subnet-mask ". $netmask . ";\n"; print OUTFILE " option domain-name ". $domainname . ";\n"; # ----- DNS Servers @temp = &rowfind('Dhcp Server ([0-9\.]*) Add Optiondef ([0-9]*) "(.*)DNS(.*)" IPADDRESS'); $trg = 'Dhcp Server ([0-9\.]*) Scope ' . $scope . ' set optionvalue ' . $temp[1] . ' IPADDRESS ([0-9\.\ \"]*)'; print ">>>$trg<<<\n"; @temp = &rowfind($trg); print OUTFILE " option domain-name-servers ". &cleanstring($temp[1]) . ";\n\n"; print OUTFILE " range.....\n"; print OUTFILE "\n }\n\n"; } print OUTFILE "# --------------------------------------------------------\n"; print OUTFILE "# Reserved IP section starts here\n"; my ($row, $myip, $mymac, $myname, $mydescr); foreach $scope (@netlist) { @elencomac = `grep -i "Add reservedip" $infile|grep "^Dhcp Server $serverip Scope $scope" | sed -e "s/.*Add reservedip //i" | sort -n -t . -k 1,1 -k 2,2 -k 3,3 -k 4,4`; print OUTFILE "# Subnet $scope reservation\n"; foreach $row (@elencomac) { if ($row =~ /([0-9\.]*) ([0-9a-fA-F]{12}) "(.*)" "(.*)" "(.*)"/) { $myip=$1; $mymac=&addcolon($2); $myname=$3; $mydescr=$4; print OUTFILE "\n\t# Reservation for $mydescr\n"; print OUTFILE "\thost $myname {\n"; print OUTFILE "\t hardware ethernet $mymac;\n"; print OUTFILE "\t fixed-address $myip;\n"; print OUTFILE "\t}\n"; } } } print OUTFILE "# end of Reserved IP section\n\n"; print OUTFILE "# --------------------------------------------------------\n"; if ($numOfScopes > 1) { print OUTFILE "}\n"; } close(OUTFILE); # -------------------------------------------------------------------- # -------------------------------------------------------------------- # -------------------------------------------------------------------- sub cleanstring() { my $mystring = shift; $mystring=~ s/\"//g; $mystring=~ s/ /,/g; $mystring=~ s/,$//; $mystring=~ s/\n//; $mystring=~ s/\r//; return $mystring; } # -------------------------------------------------------------------- sub addcolon() { my $macadd=shift; my $i; foreach $i (10,8,6,4,2) { $macadd = substr($macadd,0,$i) . ":" . substr($macadd, $i); } return $macadd; } # -------------------------------------------------------------------- sub rowfind() { my $strtarget = shift; my $row; my @retval; print "Cerco nel file: $strtarget\n"; foreach $row (@inputfile) { if($row=~/$strtarget/) { print "FOUND: $1 $2\n"; @retval= ($1, $2, $3, $4, $5); return @retval; } } return "NOT FOUND"; } # -------------------------------------------------------------------- sub print_usage () { print "Usage: $PROGNAME -i -o [-V] [-h]\n"; print " E.G.: $PROGNAME -i dhcp.dump -o dhcp.conf\n"; } # -------------------------------------------------------------------- sub print_help () { print "\n"; print "This script reads the Microsoft DHCP configuration file produced by\n"; print " C:\\temp> netsh dhcp server \\\\dhcpserver dump > dhcp.dump\n"; print "then it writes a DHCP configuration file for ISC DHCP, commonly used in Linux world.\n\n"; }