From: <ow...@us...> - 2008-07-27 13:43:56
|
Revision: 1612 http://ipcop.svn.sourceforge.net/ipcop/?rev=1612&view=rev Author: owes Date: 2008-07-27 13:44:04 +0000 (Sun, 27 Jul 2008) Log Message: ----------- This (large) commit removes ISC DHCP server and introduces dnsmasq as DHCP server. Still todo: - logging sections dhcp and dns must be combined - advanced DHCP options - enable BOOTP, dnsmasq does not allow per interface enabling Modified Paths: -------------- ipcop/trunk/config/cfgroot/general-functions.pl ipcop/trunk/config/rootfiles/common/dnsmasq ipcop/trunk/doc/Configuration-Files ipcop/trunk/html/cgi-bin/dhcp.cgi ipcop/trunk/html/cgi-bin/status.cgi ipcop/trunk/lfs/dnsmasq ipcop/trunk/lfs/ipcop ipcop/trunk/make.sh ipcop/trunk/src/misc-progs/restartdhcp.c Added Paths: ----------- ipcop/trunk/config/cfgroot/dnsmasq.conf ipcop/trunk/config/cfgroot/dnsmasq.local Removed Paths: ------------- ipcop/trunk/config/rootfiles/common/dhcp ipcop/trunk/lfs/dhcp Added: ipcop/trunk/config/cfgroot/dnsmasq.conf =================================================================== --- ipcop/trunk/config/cfgroot/dnsmasq.conf (rev 0) +++ ipcop/trunk/config/cfgroot/dnsmasq.conf 2008-07-27 13:44:04 UTC (rev 1612) @@ -0,0 +1,7 @@ +# Do not modify '/var/ipcop/dhcp/dnsmasq.conf' directly since any changes +# you make will be overwritten whenever you resave dhcp settings using the +# web interface! +# Instead modify the file '/var/ipcop/dhcp/dnsmasq.local' and then restart +# the DHCP server using the web interface. Changes made to the 'local' file +# will then propagate to the DHCP server. + Added: ipcop/trunk/config/cfgroot/dnsmasq.local =================================================================== --- ipcop/trunk/config/cfgroot/dnsmasq.local (rev 0) +++ ipcop/trunk/config/cfgroot/dnsmasq.local 2008-07-27 13:44:04 UTC (rev 1612) @@ -0,0 +1,4 @@ +# +# Used for private dnsmasq (DHCP) options. +# See dnsmasq manual http://www.thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html +# Modified: ipcop/trunk/config/cfgroot/general-functions.pl =================================================================== --- ipcop/trunk/config/cfgroot/general-functions.pl 2008-07-27 10:14:17 UTC (rev 1611) +++ ipcop/trunk/config/cfgroot/general-functions.pl 2008-07-27 13:44:04 UTC (rev 1612) @@ -853,37 +853,16 @@ map ( $buttonlist.="<input type='submit' name='ACTION_ALL' value='$_' />", split (',', shift || '' )); my ($ip, $endtime, $ether, $hostname, @record, $record); - open(LEASES,"/var/state/dhcp/dhcpd.leases") or die "Can't open dhcpd.leases"; + open(LEASES,"/var/run/dnsmasq.leases"); while (my $line = <LEASES>) { next if( $line =~ /^\s*#/ ); chomp($line); my @temp = split (' ', $line); - if ($line =~ /^\s*lease/) { - $ip = $temp[1]; - #All field are not necessarily read. Clear everything - $endtime = 0; - $ether = ""; - $hostname = ""; - } elsif ($line =~ /^\s*ends never;/) { - $endtime = 'never'; - } elsif ($line =~ /^\s*ends/) { - $line =~ /(\d+)\/(\d+)\/(\d+) (\d+):(\d+):(\d+)/; - $endtime = timegm($6, $5, $4, $3, $2 - 1, $1 - 1900); - } elsif ($line =~ /^\s*hardware ethernet/) { - $ether = $temp[2]; - $ether =~ s/;//g; - } elsif ($line =~ /^\s*client-hostname/) { - shift (@temp); - $hostname = join (' ',@temp); - $hostname =~ s/;//g; - $hostname =~ s/\"//g; - } elsif ($line eq "}") { - @record = ('IPADDR',$ip,'ENDTIME',$endtime,'ETHER',$ether,'HOSTNAME',$hostname); + @record = ('IPADDR',$temp[2],'ENDTIME',$temp[0],'ETHER',$temp[1],'HOSTNAME',$temp[3]); $record = {}; # create a reference to empty hash %{$record} = @record; # populate that hash with @record $entries{$record->{'IPADDR'}} = $record; # add this to a hash of hashes - } #unknown format line... } close(LEASES); @@ -913,7 +892,7 @@ } &Header::openbox('100%', 'left', $Lang::tr{'current dynamic leases'}); - print "<form method = 'post'>" if ($buttonlist); + print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>" if ($buttonlist); print "<table width='100%'>"; print "<tr>"; print "<td></td>" if ($buttonlist); # a new column for checkboxes @@ -966,7 +945,7 @@ print "</table>"; - print " <img src='/images/vert-horiz.png'>$buttonlist</form>" if ($buttonlist); # Issue a default command button + print " <img src='/images/vert-horiz.png' alt='' />$buttonlist</form>" if ($buttonlist); # Issue a default command button &Header::closebox(); } Deleted: ipcop/trunk/config/rootfiles/common/dhcp =================================================================== --- ipcop/trunk/config/rootfiles/common/dhcp 2008-07-27 10:14:17 UTC (rev 1611) +++ ipcop/trunk/config/rootfiles/common/dhcp 2008-07-27 13:44:04 UTC (rev 1612) @@ -1,42 +0,0 @@ -## dhcp-3.1.0 -## -#etc/dhclient.conf -etc/dhcpd.conf -#usr/bin/omshell -#usr/local/include/dhcpctl.h -#usr/local/include/isc-dhcp -#usr/local/include/isc-dhcp/boolean.h -#usr/local/include/isc-dhcp/dst.h -#usr/local/include/isc-dhcp/int.h -#usr/local/include/isc-dhcp/lang.h -#usr/local/include/isc-dhcp/list.h -#usr/local/include/isc-dhcp/result.h -#usr/local/include/isc-dhcp/types.h -#usr/local/include/omapip -#usr/local/include/omapip/alloc.h -#usr/local/include/omapip/buffer.h -#usr/local/include/omapip/omapip.h -#usr/local/lib/libdhcpctl.a -#usr/local/lib/libomapi.a -#usr/sbin/dhclient -#usr/sbin/dhclient-script -usr/sbin/dhcpd -#usr/sbin/dhcrelay -#usr/share/man/man1/omshell.1 -#usr/share/man/man3/dhcpctl.3 -#usr/share/man/man3/omapi.3 -#usr/share/man/man3/omshell.3 -#usr/share/man/man5/dhclient.conf.5 -#usr/share/man/man5/dhclient.leases.5 -#usr/share/man/man5/dhcp-eval.5 -#usr/share/man/man5/dhcp-options.5 -#usr/share/man/man5/dhcpd.conf.5 -#usr/share/man/man5/dhcpd.leases.5 -#usr/share/man/man8/dhclient-script.8 -#usr/share/man/man8/dhclient.8 -#usr/share/man/man8/dhcpd.8 -#usr/share/man/man8/dhcrelay.8 -#var/state -#var/state/dhcp -var/state/dhcp/dhcpd.leases -#var/state/dhcp/dhclient.leases Modified: ipcop/trunk/config/rootfiles/common/dnsmasq =================================================================== --- ipcop/trunk/config/rootfiles/common/dnsmasq 2008-07-27 10:14:17 UTC (rev 1611) +++ ipcop/trunk/config/rootfiles/common/dnsmasq 2008-07-27 13:44:04 UTC (rev 1612) @@ -1,2 +1,5 @@ +## dnsmasq-2.43 +## +etc/dnsmasq.conf usr/sbin/dnsmasq #usr/share/man/man8/dnsmasq.8 Modified: ipcop/trunk/doc/Configuration-Files =================================================================== --- ipcop/trunk/doc/Configuration-Files 2008-07-27 10:14:17 UTC (rev 1611) +++ ipcop/trunk/doc/Configuration-Files 2008-07-27 13:44:04 UTC (rev 1612) @@ -57,6 +57,33 @@ ================================================================================ +/var/ipcop/dhcp/settings + Contains config settings for dhcp server. + Written by dhcp.cgi. + + ENABLED_GREEN_1 on/off + ENABLED_BOOTP_GREEN_1 on/off (currently not used) + START_ADDR_GREEN_1 IP address for start of dynamic range + END_ADDR_GREEN_1 IP address for end of dynamic range + DOMAIN_NAME_GREEN_1 + DEFAULT_LEASE_TIME_GREEN_1 lease time in minutes + DNS1_GREEN_1 + DNS2_GREEN_1 + WINS1_GREEN_1 + WINS2_GREEN_1 + NTP1_GREEN_1 + NTP2_GREEN_1 + + same for BLUE + +================================================================================ + +/var/ipcop/dhcp/fixedleases + Contains the fixed leases. + Written by dhcp.cgi. + +================================================================================ + /var/ipcop/proxy/settings Contains config settings for squid proxy. Written by proxy.cgi. Modified: ipcop/trunk/html/cgi-bin/dhcp.cgi =================================================================== --- ipcop/trunk/html/cgi-bin/dhcp.cgi 2008-07-27 10:14:17 UTC (rev 1611) +++ ipcop/trunk/html/cgi-bin/dhcp.cgi 2008-07-27 13:44:04 UTC (rev 1612) @@ -1,1002 +1,566 @@ #!/usr/bin/perl # -# SmoothWall CGIs +# This file is part of the IPCop Firewall. # -# This code is distributed under the terms of the GPL +# IPCop is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License as published by +# the Free Software Foundation; either version 2 of the License, or +# (at your option) any later version. # -# (c) The SmoothWall Team +# IPCop is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. # -# Copyright (C) 01-02-2002 Graham Smith <gr...@gr...> -# - Fixed DHCP Leases added +# You should have received a copy of the GNU General Public License +# along with IPCop; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # -# $Id$ +# (c) 2001-2008 The IPCop Team # -# Franck -rewrite for two or more interface -# nov/2004 -check range is in correct subnet -# -add NTP option -# -add display sorting of actives leases -# dec/2004 -add comment field to fixed leases +# Over the years many people have changed and contributed to this file. +# Check CVS and SVN for specifics. # -# to do : choose a correct format for displaying dates -# : check 'new option' against its definition +# $Id$ +# use strict; # enable only the following on debugging purpose -#use warnings; +#use warnings; no warnings 'once'; #use CGI::Carp 'fatalsToBrowser'; require '/var/ipcop/general-functions.pl'; -require "/var/ipcop/lang.pl"; -require "/var/ipcop/header.pl"; -#workaround to suppress a warning when a variable is used only once -my @dummy = ( ${Header::colouryellow} ); -undef (@dummy); +require '/var/ipcop/lang.pl'; +require '/var/ipcop/header.pl'; -our %dhcpsettings=(); -our %netsettings=(); +&Header::showhttpheaders(); + +my %dhcpsettings=(); +my %netsettings=(); my %mainsettings=(); my %timesettings=(); -my $setting = "${General::swroot}/dhcp/settings"; -our $filename1 = "${General::swroot}/dhcp/advoptions"; # Field separator is TAB in this file (comma is standard) - # because we need commas in some data -our $filename2 = "${General::swroot}/dhcp/fixleases"; -our $filename3 = "${General::swroot}/dhcp/advoptions-list"; # List of options+syntax -our $filename4 = "${General::swroot}/dhcp/parameters-list"; # List of allowed 'parameters' ; no checking on parameters + +my $buttontext = $Lang::tr{'add'}; my $errormessage = ''; -my $error_dhcp = ''; -my $error_fixed = ''; +my $error_save_main = ''; +my $error_save_fixed = ''; my $warnmessage = ''; my $warnNTPmessage = ''; -my @nosaved=(); -# $Lang::tr{'green interface'} # Dummy string variables included here -# $Lang::tr{'blue interface'} # otherwise lang scripts will miss them -our $OptionTypes = 'boolean|((un)?signed )?integer (8|16|32)|ip-address|text|string|encapsulate \w+|' - .'array of (boolean|((un)?signed )?integer (8|16|32)|ip-address)|' - .'{(,| |boolean|((un)?signed )?integer (8|16|32)|ip-address|text|string)+}|' - .'array of {(,| |boolean|((un)?signed )?integer (8|16|32)|ip-address)+}'; +# owes: TODO add Blue only when defined +my @INTERFACEs=('GREEN','BLUE'); +my $counter; +my $key; +my $line; +my %checked=(); +my $debug = 0; -&Header::showhttpheaders(); -our @ITFs=('GREEN','BLUE'); +my $disable_main = 0; +my $disable_fixed = 1; -#Settings1 for the first screen box -foreach my $itf (@ITFs) { - $dhcpsettings{"ENABLE_${itf}"} = 'off'; - $dhcpsettings{"ENABLEBOOTP_${itf}"} = 'off'; - $dhcpsettings{"ENABLEHOSTNAMES_${itf}"} = 'off'; - $dhcpsettings{"START_ADDR_${itf}"} = ''; - $dhcpsettings{"END_ADDR_${itf}"} = ''; - $dhcpsettings{"BASE_IP_FIXED_LEASE_${itf}"} = ''; - $dhcpsettings{"DOMAIN_NAME_${itf}"} = ''; - $dhcpsettings{"DEFAULT_LEASE_TIME_${itf}"} = ''; - $dhcpsettings{"MAX_LEASE_TIME_${itf}"} = ''; - $dhcpsettings{"WINS1_${itf}"} = ''; - $dhcpsettings{"WINS2_${itf}"} = ''; - $dhcpsettings{"DNS1_${itf}"} = ''; - $dhcpsettings{"DNS2_${itf}"} = ''; - $dhcpsettings{"NTP1_${itf}"} = ''; - $dhcpsettings{"NTP2_${itf}"} = ''; - $dhcpsettings{"NIS_${itf}"} = ''; -} +# get IPCop settings +&General::readhash('/var/ipcop/ethernet/settings', \%netsettings); +&General::readhash('/var/ipcop/main/settings', \%mainsettings); +&General::readhash('/var/ipcop/time/settings', \%timesettings); -$dhcpsettings{'SORT_FLEASELIST'} = 'FIPADDR'; -$dhcpsettings{'SORT_LEASELIST'} = 'IPADDR'; - -#Settings2 for editing the multi-line list -#Must not be saved with writehash ! -$dhcpsettings{'FIX_MAC'} = ''; -$dhcpsettings{'FIX_ADDR'} = ''; -$dhcpsettings{'FIX_ENABLED'} = 'off'; -$dhcpsettings{'FIX_NEXTADDR'} = ''; -$dhcpsettings{'FIX_FILENAME'} = ''; -$dhcpsettings{'FIX_ROOTPATH'} = ''; -$dhcpsettings{'FIX_REMARK'} = ''; -$dhcpsettings{'FIX_HOSTNAME'} = ''; -$dhcpsettings{'FIX_ROUTER'} = ''; -$dhcpsettings{'FIX_DNS'} = ''; +# main settings +foreach my $interface (@INTERFACEs) +{ + for ($counter = 1; $counter <= 1; $counter++) + { + $dhcpsettings{"ENABLED_${interface}_${counter}"} = 'off'; + $dhcpsettings{"ENABLED_BOOTP_${interface}_${counter}"} = 'off'; + $dhcpsettings{"START_ADDR_${interface}_${counter}"} = ''; + $dhcpsettings{"END_ADDR_${interface}_${counter}"} = ''; + $dhcpsettings{"DOMAIN_NAME_${interface}_${counter}"} = ''; + $dhcpsettings{"DEFAULT_LEASE_TIME_${interface}_${counter}"} = '60'; + $dhcpsettings{"DNS1_${interface}_${counter}"} = $netsettings{"${interface}_${counter}_ADDRESS"}; + $dhcpsettings{"DNS2_${interface}_${counter}"} = ''; + $dhcpsettings{"WINS1_${interface}_${counter}"} = ''; + $dhcpsettings{"WINS2_${interface}_${counter}"} = ''; + $dhcpsettings{"NTP1_${interface}_${counter}"} = ''; + $dhcpsettings{"NTP2_${interface}_${counter}"} = ''; + } +} $dhcpsettings{'ACTION'} = ''; -$dhcpsettings{'KEY1'} = ''; -$dhcpsettings{'KEY2'} = ''; -@nosaved=('FIX_MAC','FIX_ADDR','FIX_ENABLED','FIX_NEXTADDR','FIX_FILENAME', - 'FIX_ROOTPATH','FIX_REMARK','FIX_HOSTNAME','FIX_ROUTER','FIX_DNS'); +$dhcpsettings{'SORT_FIXEDLEASELIST'} = ''; +$dhcpsettings{'FIXED_ENABLED'} = ''; +$dhcpsettings{'FIXED_MAC'} = ''; +$dhcpsettings{'FIXED_IP'} = ''; +$dhcpsettings{'FIXED_REMARK'} = ''; +$dhcpsettings{'FIXED_HOSTNAME'} = ''; +$dhcpsettings{'FIXED_NEXTADDR'} = ''; +$dhcpsettings{'FIXED_FILENAME'} = ''; +$dhcpsettings{'FIXED_ROOTPATH'} = ''; +$dhcpsettings{'KEY_FIXED'} = ''; -$dhcpsettings{'ADVOPT_ENABLED'} = ''; -$dhcpsettings{'ADVOPT_NAME'} = ''; -$dhcpsettings{'ADVOPT_DATA'} = ''; -unshift (@nosaved,'ADVOPT_ENABLED','ADVOPT_NAME','ADVOPT_DATA'); -foreach my $itf (@ITFs) { - $dhcpsettings{"ADVOPT_SCOPE_${itf}"} = 'off'; - unshift (@nosaved, "ADVOPT_SCOPE_${itf}"); -} +# read the fixed leases +my @fixedleases; +open(FILE, '/var/ipcop/dhcp/fixedleases'); +@fixedleases = <FILE>; +close(FILE); -# Read Ipcop settings -&General::readhash("${General::swroot}/ethernet/settings", \%netsettings); -&General::readhash("${General::swroot}/main/settings", \%mainsettings); -&General::readhash("${General::swroot}/time/settings", \%timesettings); - -#Get GUI values &General::getcgihash(\%dhcpsettings); -open(FILE, "$filename1") or die 'Unable to open dhcp advanced options file.'; -our @current1 = <FILE>; -close(FILE); -# Extract OptionDefinition -foreach my $line (@current1) { - #chomp($line); # remove newline #don't know why, but this remove newline in @current1 .... ! - my @temp = split(/\t/,$line); - AddNewOptionDefinition ($temp[1] . ' ' . $temp[2]); +&Header::openpage($Lang::tr{'dhcp configuration'}, 1, ''); +&Header::openbigbox('100%', 'left', '', ''); + +############### +# DEBUG DEBUG +if ( $debug ) +{ +&Header::openbox('100%', 'left', 'DEBUG'); +my $debugCount = 0; +foreach my $line (sort keys %dhcpsettings) { + print "$line = $dhcpsettings{$line}<br />\n"; + $debugCount++; } +print " Count: $debugCount\n"; +&Header::closebox(); +} +# DEBUG DEBUG +############### -open(FILE, "$filename2") or die 'Unable to open fixed leases file.'; -our @current2 = <FILE>; -close(FILE); -# Check Settings1 first because they are needed by &buildconf -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'save'}) { - foreach my $itf (@ITFs) { - if ($dhcpsettings{"ENABLE_${itf}"} eq 'on' ) { - # "Start" is defined, need "End" and vice versa - if ($dhcpsettings{"START_ADDR_${itf}"}) { - if (!(&General::validip($dhcpsettings{"START_ADDR_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid start address'}; - goto ERROR; - } - if (!$dhcpsettings{"END_ADDR_${itf}"}) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid end address'}; - goto ERROR; - } - if (! &General::IpInSubnet ( $dhcpsettings{"START_ADDR_${itf}"}, - $netsettings{"${itf}_NETADDRESS"}, - $netsettings{"${itf}_NETMASK"})) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid start address'}; - goto ERROR; - } - } +if ( $dhcpsettings{'ACTION'} eq 'SAVE_MAIN' ) +{ + # Verify the options before writing anything + foreach my $interface (@INTERFACEs) + { + # Limit to 1 interface for now + for ($counter = 1; $counter <= 1; $counter++) + { + if ( $dhcpsettings{"ENABLED_${interface}_${counter}"} eq 'on' ) { - if ($dhcpsettings{"END_ADDR_${itf}"}) { - if (!(&General::validip($dhcpsettings{"END_ADDR_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid end address'}; - goto ERROR; - } - if (!$dhcpsettings{"START_ADDR_${itf}"}) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid start address'}; - goto ERROR; - } - if (! &General::IpInSubnet ( $dhcpsettings{"END_ADDR_${itf}"}, - $netsettings{"${itf}_NETADDRESS"}, - $netsettings{"${itf}_NETMASK"})) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid end address'}; - goto ERROR; - } - #swap if necessary! (support 255.255.0.0 range, I doubt we need more) GE - my @startoct = split (/\./, $dhcpsettings{"START_ADDR_${itf}"}); - my @endoct = split (/\./, $dhcpsettings{"END_ADDR_${itf}"}); - if ( $endoct[2]*256+$endoct[3] < $startoct[2]*256+$startoct[3] ) { - ($dhcpsettings{"START_ADDR_${itf}"},$dhcpsettings{"END_ADDR_${itf}"}) = - ($dhcpsettings{"END_ADDR_${itf}"},$dhcpsettings{"START_ADDR_${itf}"}); - } - } + # define START and END or leave both empty (for static leases only) + if ( $dhcpsettings{"START_ADDR_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"START_ADDR_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid start address'}; + goto ERROR_SAVE_MAIN; + } + if ( !$dhcpsettings{"END_ADDR_${interface}_${counter}"} ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid end address'}; + goto ERROR_SAVE_MAIN; + } + if ( ! &General::IpInSubnet ( $dhcpsettings{"START_ADDR_${interface}_${counter}"}, + $netsettings{"${interface}_${counter}_NETADDRESS"}, + $netsettings{"${interface}_${counter}_NETMASK"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid start address'}; + goto ERROR_SAVE_MAIN; + } + } + if ( $dhcpsettings{"END_ADDR_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"END_ADDR_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid end address'}; + goto ERROR_SAVE_MAIN; + } + if ( !$dhcpsettings{"START_ADDR_${interface}_${counter}"} ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid start address'}; + goto ERROR_SAVE_MAIN; + } + if ( ! &General::IpInSubnet ( $dhcpsettings{"END_ADDR_${interface}_${counter}"}, + $netsettings{"${interface}_${counter}_NETADDRESS"}, + $netsettings{"${interface}_${counter}_NETMASK"})) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid end address'}; + goto ERROR_SAVE_MAIN; + } + } - if (!($dhcpsettings{"DEFAULT_LEASE_TIME_${itf}"} =~ /^\d+$/)) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid default lease time'} . $dhcpsettings{'DEFAULT_LEASE_TIME_${itf}'}; - goto ERROR; - } + # Lease time must be set and be numeric + if ( ! ($dhcpsettings{"DEFAULT_LEASE_TIME_${interface}_${counter}"} =~ /^\d+$/) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid default lease time'} . ' ' . $dhcpsettings{'DEFAULT_LEASE_TIME_${interface}_${counter}'}; + goto ERROR_SAVE_MAIN; + } - if (!($dhcpsettings{"MAX_LEASE_TIME_${itf}"} =~ /^\d+$/)) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid max lease time'} . $dhcpsettings{'MAX_LEASE_TIME_${itf}'}; - goto ERROR; - } + # Verify DNS1 and DNS2 + if ( $dhcpsettings{"DNS1_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"DNS1_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid primary dns'}; + goto ERROR_SAVE_MAIN; + } + } + if ( $dhcpsettings{"DNS2_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"DNS2_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid secondary dns'}; + goto ERROR_SAVE_MAIN; + } + if ( ! $dhcpsettings{"DNS1_${interface}_${counter}"} ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'cannot specify secondary dns without specifying primary'}; + goto ERROR_SAVE_MAIN; + } + } - if ($dhcpsettings{"BASE_IP_FIXED_LEASE_${itf}"}) { - if (!(&General::validip($dhcpsettings{"BASE_IP_FIXED_LEASE_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " .$Lang::tr{'dhcp base ip fixed lease'}. ' '. $Lang::tr{'invalid ip'} ; - goto ERROR; - } - } + # Verify WINS1 and WINS2 + if ( $dhcpsettings{"WINS1_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"WINS1_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid wins address'}; + goto ERROR_SAVE_MAIN; + } + } + if ( $dhcpsettings{"WINS2_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"WINS2_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid wins address'}; + goto ERROR_SAVE_MAIN; + } + if ( ! $dhcpsettings{"WINS1_${interface}_${counter}"} ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'cannot specify secondary wins without specifying primary'}; + goto ERROR_SAVE_MAIN; + } + } - if ($dhcpsettings{"DNS1_${itf}"}) { - if (!(&General::validip($dhcpsettings{"DNS1_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid primary dns'}; - goto ERROR; + # Verify NTP1 and NTP2 + if ( $dhcpsettings{"NTP1_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"NTP1_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid primary ntp'}; + goto ERROR_SAVE_MAIN; + } + if ( ($dhcpsettings{"NTP1_${interface}_${counter}"} eq $netsettings{"${interface}_ADDRESS"}) && ($timesettings{'ENABLENTP'} ne 'on') ) { + $warnNTPmessage = "DHCP on ${interface}: " . $Lang::tr{'local ntp server specified but not enabled'}; + } + } + if ( $dhcpsettings{"NTP2_${interface}_${counter}"} ) { + if ( ! &General::validip($dhcpsettings{"NTP2_${interface}_${counter}"}) ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'invalid secondary ntp'}; + goto ERROR_SAVE_MAIN; + } + if ( ($dhcpsettings{"NTP2_${interface}_${counter}"} eq $netsettings{"${interface}_ADDRESS"}) && ($timesettings{'ENABLENTP'} ne 'on') ) { + $warnNTPmessage = "DHCP on ${interface}: " . $Lang::tr{'local ntp server specified but not enabled'}; + } + if ( ! $dhcpsettings{"NTP1_${interface}_${counter}"} ) { + $errormessage = "DHCP on ${interface}: " . $Lang::tr{'cannot specify secondary ntp without specifying primary'}; + goto ERROR_SAVE_MAIN; + } + } } - } - if ($dhcpsettings{"DNS2_${itf}"}) { - if (!(&General::validip($dhcpsettings{"DNS2_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid secondary dns'}; - goto ERROR; - } - if (! $dhcpsettings{"DNS1_${itf}"}) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'cannot specify secondary dns without specifying primary'}; - goto ERROR; - } - } - - if ($dhcpsettings{"WINS1_${itf}"}) { - if (!(&General::validip($dhcpsettings{"WINS1_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid wins address'}; - goto ERROR; - } - } - if ($dhcpsettings{"WINS2_${itf}"}) { - if (!(&General::validip($dhcpsettings{"WINS2_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid wins address'}; - goto ERROR; - } - if (! $dhcpsettings{"WINS1_${itf}"} ) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'cannot specify secondary wins without specifying primary'}; - goto ERROR; - } - } - - if ($dhcpsettings{"NTP1_${itf}"}) { - if (!(&General::validip($dhcpsettings{"NTP1_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid primary ntp'}; - goto ERROR; - } - if ($dhcpsettings{"NTP1_${itf}"} eq $netsettings{"${itf}_ADDRESS"} && ($timesettings{'ENABLENTP'} ne 'on')) { - $warnNTPmessage = "DHCP on ${itf}: " . $Lang::tr{'local ntp server specified but not enabled'}; - #goto ERROR; - } - } - if ($dhcpsettings{"NTP2_${itf}"}) { - if (!(&General::validip($dhcpsettings{"NTP2_${itf}"}))) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid secondary ntp'}; - goto ERROR; - } - if ($dhcpsettings{"NTP2_${itf}"} eq $netsettings{"${itf}_ADDRESS"} && ($timesettings{'ENABLENTP'} ne 'on')) { - $warnNTPmessage = "DHCP on ${itf}: " . $Lang::tr{'local ntp server specified but not enabled'}; - #goto ERROR; - } - if (! $dhcpsettings{"NTP1_${itf}"}) { - $errormessage = "DHCP on ${itf}: " . $Lang::tr{'cannot specify secondary ntp without specifying primary'}; - goto ERROR; - } - } - } # enabled - }#loop interface verify - - map (delete ($dhcpsettings{$_}) ,@nosaved,'ACTION','KEY1','KEY2'); # Must not be saved - &General::writehash($setting, \%dhcpsettings); # Save good settings - $dhcpsettings{'ACTION'} = $Lang::tr{'save'}; # create an 'ACTION' - map ($dhcpsettings{$_} = '',@nosaved,'KEY1','KEY2'); # and reinit vars to empty - &buildconf; - ERROR: # Leave the faulty field untouched - $error_dhcp = 'error' if ($errormessage); -} else { - &General::readhash($setting, \%dhcpsettings); # Get saved settings and reset to good if needed + } # interface count + } # foreach interface + &writeconfig(1); +ERROR_SAVE_MAIN: + $error_save_main = 'error' if ( $errormessage ); } - -## Sorting of fixed leases -if ($ENV{'QUERY_STRING'} =~ /^FETHER|^FIPADDR/ ) { - my $newsort=$ENV{'QUERY_STRING'}; - my $act=$dhcpsettings{'SORT_FLEASELIST'}; - #Reverse actual sort ? - if ($act =~ $newsort) { - my $Rev=''; - if ($act !~ 'Rev') { - $Rev='Rev'; - } - $newsort.=$Rev; - } - $dhcpsettings{'SORT_FLEASELIST'}=$newsort; - map (delete ($dhcpsettings{$_}) ,@nosaved,'ACTION','KEY1','KEY2'); # Must never be saved - &General::writehash($setting, \%dhcpsettings); - &sortcurrent2; - $dhcpsettings{'ACTION'} = 'SORT'; # create an 'ACTION' - map ($dhcpsettings{$_} = '',@nosaved,'KEY1','KEY2');# and reinit vars to empty +else +{ + &General::readhash('/var/ipcop/dhcp/settings', \%dhcpsettings); } -#Sorting of allocated leases -&General::CheckSortOrder; +if ( $dhcpsettings{'ACTION'} eq $Lang::tr{'toggle enable disable'}.'_fixed') +{ + # Toggle enable/disable field on specified fixed lease -## Now manipulate the two multi-line list with Settings2. -# '1' suffix is for ADVANCED OPTIONS -# '2' suffix is for FIXED LEASES + chomp(@fixedleases[$dhcpsettings{'KEY_FIXED'}]); + my @temp = split(/\,/,@fixedleases[$dhcpsettings{'KEY_FIXED'}]); + $temp[2] = $temp[2] eq 'on' ? '' : 'on'; + @fixedleases[$dhcpsettings{'KEY_FIXED'}] = join (',',@temp)."\n"; + $dhcpsettings{'KEY_FIXED'} = ''; # forget we were editing something + &writefixedleases(1); +} -# Toggle enable/disable field on specified options. +if ($dhcpsettings{'ACTION'} eq $Lang::tr{'edit'}.'_fixed') +{ + # Edit fields on specified fixed lease -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'toggle enable disable'}.'1') { - #move out new line - chomp(@current1[$dhcpsettings{'KEY1'}]); - my @temp = split(/\t/,@current1[$dhcpsettings{'KEY1'}]); #use TAB separator ! - $temp[0] = $temp[0] eq 'on' ? '' : 'on'; # Toggle the field - @current1[$dhcpsettings{'KEY1'}] = join ("\t",@temp)."\n"; - $dhcpsettings{'KEY1'} = ''; # End edit mode - &General::log($Lang::tr{'dhcp advopt modified'}); - open(FILE, ">$filename1") or die 'Unable to open dhcp advanced options file.'; - print FILE @current1; - close(FILE); + $disable_main = 1; + $disable_fixed = 0; - #Write changes to dhcpd.conf. - &buildconf; + chomp(@fixedleases[$dhcpsettings{'KEY_FIXED'}]); + my @temp = split(/\,/,@fixedleases[$dhcpsettings{'KEY_FIXED'}]); + $dhcpsettings{'FIXED_ENABLED'} = $temp[2]; + $dhcpsettings{'FIXED_MAC'} = $temp[0]; + $dhcpsettings{'FIXED_IP'} = $temp[1]; + $dhcpsettings{'FIXED_REMARK'} = $temp[6]; + $dhcpsettings{'FIXED_HOSTNAME'} = $temp[7]; + $dhcpsettings{'FIXED_NEXTADDR'} = $temp[3]; + $dhcpsettings{'FIXED_FILENAME'} = $temp[4]; + $dhcpsettings{'FIXED_ROOTPATH'} = $temp[5]; } +if ($dhcpsettings{'ACTION'} eq $Lang::tr{'remove'}.'_fixed') +{ + # Remove a fixed lease -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'add'}.'1' && - $dhcpsettings{'SUBMIT'} ne $Lang::tr{'dhcp advopt help'}) { + splice (@fixedleases, $dhcpsettings{'KEY_FIXED'}, 1); + $dhcpsettings{'KEY_FIXED'} = ''; # forget we were editing something + &writefixedleases(1); +} - #If input box ADVOPT_NAME is empty, get value from the select; - $dhcpsettings{'ADVOPT_NAME'} = $dhcpsettings{'ADVOPT_LIST'} if ( ! $dhcpsettings{'ADVOPT_NAME'} ); +if ( $dhcpsettings{'ACTION'} eq 'ADD_FIXED_LEASE' ) +{ + # Button to add fixed lease was pressed - $dhcpsettings{'ADVOPT_NAME'} =~ s/[^ \w-]//g; # prevent execution of code by removing everything except letters/space - $dhcpsettings{'ADVOPT_DATA'} =~ s/`//g; # back tik ` ? not allowed ! + $disable_main = 1; + $disable_fixed = 0; + $dhcpsettings{'FIXED_ENABLED'} = 'on'; # on per default +} - if ($dhcpsettings{'ADVOPT_DATA'} eq '') { - $errormessage=$Lang::tr{'dhcp advopt blank value'}; - } +if ( $dhcpsettings{'ACTION'} eq 'SAVE_FIXED_LEASE' ) +{ + # Verify the options before writing anything - # Test for a new option definition string (join field name & data) - if (ExistNewOptionDefinition ($dhcpsettings{'ADVOPT_NAME'} . ' ' . $dhcpsettings{'ADVOPT_DATA'})) { - #only edit permitted if option definition exists - $errormessage = $Lang::tr{'dhcp advopt definition exists'} if ($dhcpsettings{'KEY1'} eq ''); - $dhcpsettings{'ADVOPT_ENABLED'} = 'on'; # force active - map ($dhcpsettings{"ADVOPT_SCOPE_$_"} = 'off', @ITFs); # force global - } elsif (AddNewOptionDefinition ($dhcpsettings{'ADVOPT_NAME'} . ' ' . $dhcpsettings{'ADVOPT_DATA'})) { - #was a new option definition - $dhcpsettings{'ADVOPT_ENABLED'} = 'on'; # force active - map ($dhcpsettings{"ADVOPT_SCOPE_$_"} = 'off', @ITFs); # force global - } elsif (ValidNewOption ($dhcpsettings{'ADVOPT_NAME'} . ' ' . $dhcpsettings{'ADVOPT_DATA'})) { - #was a new option, only editing or adding one instance is allowed - if ($dhcpsettings{'KEY1'} eq '') { - foreach my $line (@current1) { - #chomp($line); # remove newline #don't know why, but this remove newline in @current1 .... ! - my @temp = split(/\t/,$line); - #I know, the message is not perfectly exact. - $errormessage = $Lang::tr{'dhcp advopt definition exists'} - if (($dhcpsettings{'ADVOPT_NAME'} eq $temp[1]) && ($temp[2] !~ /code \d+=/)); - } + $dhcpsettings{'FIXED_MAC'} =~ tr/-/:/; + if ( ! &General::validmac($dhcpsettings{'FIXED_MAC'}) ) + { + $errormessage = $Lang::tr{'invalid fixed mac address'}; + goto ERROR_SAVE_FIXED; } - } elsif (! `/bin/grep "^option $dhcpsettings{'ADVOPT_NAME'} " $filename3` && - ! `/bin/grep "^$dhcpsettings{'ADVOPT_NAME'}" $filename4`) { - $warnmessage=$Lang::tr{'dhcp advopt unknown'}.': '.$dhcpsettings{'ADVOPT_NAME'}; - } - unless ($errormessage) { - - my $scope = ''; - foreach my $itf (@ITFs) { # buils "RED,GREEN,ORANGE,... based on selection - $scope .= $dhcpsettings{"ADVOPT_SCOPE_${itf}"} eq 'on' ? "\t$itf" : "\toff" ; + if ( ! &General::validip($dhcpsettings{'FIXED_IP'}) ) + { + $errormessage = $Lang::tr{'invalid fixed ip address'}; + goto ERROR_SAVE_FIXED; } - if ($dhcpsettings{'KEY1'} eq '') { #add or edit ? TAB separator ! - unshift (@current1, "$dhcpsettings{'ADVOPT_ENABLED'}\t$dhcpsettings{'ADVOPT_NAME'}\t$dhcpsettings{'ADVOPT_DATA'}$scope\n"); - &General::log($Lang::tr{'dhcp advopt added'}); - } else { - @current1[$dhcpsettings{'KEY1'}] = "$dhcpsettings{'ADVOPT_ENABLED'}\t$dhcpsettings{'ADVOPT_NAME'}\t$dhcpsettings{'ADVOPT_DATA'}$scope\n"; - $dhcpsettings{'KEY1'} = ''; # End edit mode - &General::log($Lang::tr{'dhcp advopt modified'}); - } - #Write changes to dhcpd.conf. - &sortcurrent1; # sort newly added/modified entry - &buildconf; # before calling buildconf which use fixed lease file ! - } -} - -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'edit'}.'1') { - #move out new line - my $line = @current1[$dhcpsettings{'KEY1'}]; - chomp($line); - my @temp = split(/\t/, $line); - $dhcpsettings{'ADVOPT_ENABLED'}=$temp[0]; - $dhcpsettings{'ADVOPT_NAME'}=$temp[1]; - $dhcpsettings{'ADVOPT_DATA'}=$temp[2]; - - # read next fields which are the name (color) of an interface if this interface is scoped - for (my $key=0; $key<@ITFs; $key++) { - my $itf = $temp[3+$key]; - if ($itf ne 'off') # Only is an interface name is read + if ( $dhcpsettings{'KEY_FIXED'} ne '' ) { - $dhcpsettings{"ADVOPT_SCOPE_${itf}"} = 'on'; + # replace existing + @fixedleases[$dhcpsettings{'KEY_FIXED'}] = "$dhcpsettings{'FIXED_MAC'},$dhcpsettings{'FIXED_IP'},$dhcpsettings{'FIXED_ENABLED'},". + "$dhcpsettings{'FIXED_NEXTADDR'},$dhcpsettings{'FIXED_FILENAME'},$dhcpsettings{'FIXED_ROOTPATH'},". + "$dhcpsettings{'FIXED_REMARK'},$dhcpsettings{'FIXED_HOSTNAME'}\n"; } - } -} - -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'remove'}.'1') { - splice (@current1,$dhcpsettings{'KEY1'},1); - open(FILE, ">$filename1") or die 'Unable to open dhcp advanced options file.'; - print FILE @current1; - close(FILE); - $dhcpsettings{'KEY1'} = ''; # End remove mode - &General::log($Lang::tr{'dhcp advopt removed'}); - #Write changes to dhcpd.conf. - &buildconf; -} -#end KEY1 - - -# Toggle enable/disable field on specified lease. -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'toggle enable disable'}.'2') { - #move out new line - chomp(@current2[$dhcpsettings{'KEY2'}]); - my @temp = split(/\,/,@current2[$dhcpsettings{'KEY2'}]); - $temp[2] = $temp[2] eq 'on' ? '' : 'on'; # Toggle the field - @current2[$dhcpsettings{'KEY2'}] = join (',',@temp)."\n"; - $dhcpsettings{'KEY2'} = ''; # End edit mode - &General::log($Lang::tr{'fixed ip lease modified'}); - open(FILE, ">$filename2") or die 'Unable to open fixed leases file.'; - print FILE @current2; - close(FILE); - - #Write changes to dhcpd.conf. - &buildconf; -} - -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'add'}.'2') { - - $errormessage = $Lang::tr{'dhcp fixed lease err1'} - if ( ($dhcpsettings{'FIX_HOSTNAME'} eq '') && ($dhcpsettings{'FIX_MAC'} eq '')); - $errormessage = myvalidiporfqdn ($dhcpsettings{'FIX_ADDR'}, $errormessage); - $errormessage = myvalidiporfqdn ($dhcpsettings{'FIX_NEXTADDR'}, $errormessage) - if($dhcpsettings{'FIX_NEXTADDR'}); - $errormessage = myvalidiporfqdn ($dhcpsettings{'FIX_ROUTER'}, $errormessage) - if($dhcpsettings{'FIX_ROUTER'}); - $errormessage = myvalidiporfqdn ($dhcpsettings{'FIX_DNS'}, $errormessage) - if($dhcpsettings{'FIX_DNS'}); - - my $key = 0; - if ($dhcpsettings{'FIX_MAC'} ne '' ) { - $dhcpsettings{'FIX_MAC'} =~ tr/-/:/; - $errormessage = $Lang::tr{'invalid fixed mac address'} if ( ! &General::validmac($dhcpsettings{'FIX_MAC'})); - - CHECK:foreach my $line (@current2) { - my @temp = split(/\,/,$line); - if($dhcpsettings{'KEY2'} ne $key) { - # same MAC is OK on different subnets. This test is not complete because - # if IP are not inside a known subnet, I don't warn. - # Also it may be needed to put duplicate fixed lease in their right subnet definition.. - foreach my $itf (@ITFs) { - my $scoped = &General::IpInSubnet($dhcpsettings{'FIX_ADDR'}, - $netsettings{"${itf}_NETADDRESS"}, - $netsettings{"${itf}_NETMASK"}) && - $dhcpsettings{"ENABLE_${itf}"} eq 'on'; - if ( $scoped && - (lc($dhcpsettings{'FIX_MAC'}) eq lc($temp[0])) && - &General::IpInSubnet($temp[1], - $netsettings{"${itf}_NETADDRESS"}, - $netsettings{"${itf}_NETMASK"})) { - $errormessage = "$Lang::tr{'mac address in use'} $dhcpsettings{'FIX_MAC'}"; - last CHECK; - } - } - } - $key++; + else + { + # add new + unshift (@fixedleases, "$dhcpsettings{'FIXED_MAC'},$dhcpsettings{'FIXED_IP'},$dhcpsettings{'FIXED_ENABLED'},". + "$dhcpsettings{'FIXED_NEXTADDR'},$dhcpsettings{'FIXED_FILENAME'},$dhcpsettings{'FIXED_ROOTPATH'},". + "$dhcpsettings{'FIXED_REMARK'},$dhcpsettings{'FIXED_HOSTNAME'}\n"); } - } + $dhcpsettings{'KEY_FIXED'} = ''; # forget we were editing something + &writefixedleases(1); - unless ($errormessage) { - $dhcpsettings{'FIX_REMARK'} = &Header::cleanhtml($dhcpsettings{'FIX_REMARK'}); - $dhcpsettings{'FIX_NEXTADDR'} = &Header::cleanhtml($dhcpsettings{'FIX_NEXTADDR'}); - $dhcpsettings{'FIX_HOSTNAME'} = &Header::cleanhtml($dhcpsettings{'FIX_HOSTNAME'}); - $dhcpsettings{'FIX_ROUTER'} = &Header::cleanhtml($dhcpsettings{'FIX_ROUTER'}); - $dhcpsettings{'FIX_DNS'} = &Header::cleanhtml($dhcpsettings{'FIX_DNS'}); - # remove some character unallowed in a filename, replace the comma with , - $dhcpsettings{'FIX_FILENAME'} =~ s/[<">?|*;&`]//g; #` - $dhcpsettings{'FIX_FILENAME'} =~ s/,/,/g; - $dhcpsettings{'FIX_ROOTPATH'} =~ s/[<">?|*;&`]//g; #` - $dhcpsettings{'FIX_ROOTPATH'} =~ s/,/,/g; - - if ($dhcpsettings{'KEY2'} eq '') { #add or edit ? - unshift (@current2, "$dhcpsettings{'FIX_MAC'},$dhcpsettings{'FIX_ADDR'},$dhcpsettings{'FIX_ENABLED'},". - "$dhcpsettings{'FIX_NEXTADDR'},$dhcpsettings{'FIX_FILENAME'},$dhcpsettings{'FIX_ROOTPATH'},". - "$dhcpsettings{'FIX_REMARK'},$dhcpsettings{'FIX_HOSTNAME'},$dhcpsettings{'FIX_ROUTER'},". - "$dhcpsettings{'FIX_DNS'}\n"); - &General::log($Lang::tr{'fixed ip lease added'}); - } else { - @current2[$dhcpsettings{'KEY2'}] = "$dhcpsettings{'FIX_MAC'},$dhcpsettings{'FIX_ADDR'},". - "$dhcpsettings{'FIX_ENABLED'},$dhcpsettings{'FIX_NEXTADDR'},$dhcpsettings{'FIX_FILENAME'},". - "$dhcpsettings{'FIX_ROOTPATH'},$dhcpsettings{'FIX_REMARK'},$dhcpsettings{'FIX_HOSTNAME'},". - "$dhcpsettings{'FIX_ROUTER'},$dhcpsettings{'FIX_DNS'}\n"; - $dhcpsettings{'KEY2'} = ''; # End edit mode - &General::log($Lang::tr{'fixed ip lease modified'}); +ERROR_SAVE_FIXED: + if ( $errormessage ) + { + $error_save_fixed = 'error'; + $disable_main = 1; + $disable_fixed = 0; } - - #Write changes to dhcpd.conf. - &sortcurrent2; # sort newly added/modified entry - &buildconf; # before calling buildconf which use fixed lease file ! - } else { - $error_fixed = 'error'; - } } + # -# Look for all cgi variables names matching "IP-macaddress" format -# and create if necessary a fixed lease for it (the plus operator) +# Sorting of fixed leases # -# This var will passed hidden to mark the new lease -my $newmacs = ''; -if ($dhcpsettings{'ACTION_ALL'} eq $Lang::tr{'dhcp create fixed leases'}) { - foreach (keys %dhcpsettings) { - if (/^(\d+\.\d+\.\d+\.\d+)!([0-9a-fA-F:]+)!(.*)$/) { # checked names are index of the line - my $ip=$1; - my $mac=$2; - my $comment = $3 || 'imported'; +if ( $ENV{'QUERY_STRING'} =~ /^FIXEDMAC|^FIXEDIP/ ) +{ + my $newsort = $ENV{'QUERY_STRING'}; + my $act = $dhcpsettings{'SORT_FIXEDLEASELIST'}; - if (!grep (/$2/,@current2) && General::validip($ip) ) { # new mac address - - my $proposed_ip = 0; - # determine which interface $ip belongs to so that we use the auto_start_lease or end_addr - foreach my $itf (@ITFs) { - if ($dhcpsettings{"ENABLE_${itf}"} eq 'on' && - &General::IpInSubnet ( $ip, - $netsettings{"${itf}_NETADDRESS"}, - $netsettings{"${itf}_NETMASK"})) { - - $proposed_ip = $dhcpsettings{"BASE_IP_FIXED_LEASE_${itf}"} ? - $dhcpsettings{"BASE_IP_FIXED_LEASE_${itf}"} : - &General::NextIP( $dhcpsettings{"END_ADDR_${itf}"} ); - } + #Reverse actual sort ? + if ( $act =~ $newsort ) + { + my $rev=''; + if ( $act !~ 'Rev' ) + { + $rev = 'Rev'; } - - if (! $proposed_ip) { # use the current ip not 'ranged' - $proposed_ip = $ip; - } else { # starting a prposed_ip, increment it til not referenced in lease table - while ( grep (/$proposed_ip/, @current2)) { - $proposed_ip = &General::NextIP( $proposed_ip ); - } - } - unshift (@current2, "$mac,$proposed_ip,on,,,,$comment\n"); - $newmacs .= "$mac!"; - } - } - } - if ($newmacs) { - #Write changes to dhcpd.conf. - $warnNTPmessage = $Lang::tr{'fixed ip lease added'} . ' (' . length($newmacs)/18 . ')'; - &General::log($warnNTPmessage); - &sortcurrent2; # sort newly added/modified entry - &buildconf; # before calling buildconf which use fixed lease file ! - } -} - -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'edit'}.'2') { - #move out new line - my $line = @current2[$dhcpsettings{'KEY2'}]; - chomp($line); - my @temp = split(/\,/, $line); - $dhcpsettings{'FIX_MAC'}=$temp[0]; - $dhcpsettings{'FIX_ADDR'}=$temp[1]; - $dhcpsettings{'FIX_ENABLED'}=$temp[2]; - $dhcpsettings{'FIX_NEXTADDR'}=$temp[3]; - $dhcpsettings{'FIX_FILENAME'}=$temp[4]; - $dhcpsettings{'FIX_ROOTPATH'}=$temp[5]; - $dhcpsettings{'FIX_REMARK'}=$temp[6]; - $dhcpsettings{'FIX_HOSTNAME'}=$temp[7]; - $dhcpsettings{'FIX_ROUTER'}=$temp[8]; - $dhcpsettings{'FIX_DNS'}=$temp[9]; -} - -if ($dhcpsettings{'ACTION'} eq $Lang::tr{'remove'}.'2') { - splice (@current2,$dhcpsettings{'KEY2'},1); - open(FILE, ">$filename2") or die 'Unable to open fixed lease file.'; - print FILE @current2; - close(FILE); - $dhcpsettings{'KEY2'} = ''; # End remove mode - &General::log($Lang::tr{'fixed ip lease removed'}); - #Write changes to dhcpd.conf. - &buildconf; -} -#end KEY2 defined - -if ($dhcpsettings{'ACTION'} eq '' ) { # First launch from GUI - - # Set default DHCP values only if blank and disabled - foreach my $itf (@ITFs) { - if ($dhcpsettings{"ENABLE_${itf}"} ne 'on' ) { - $dhcpsettings{"DNS1_${itf}"} = $netsettings{"${itf}_ADDRESS"}; - $dhcpsettings{"DEFAULT_LEASE_TIME_${itf}"} = '60'; - $dhcpsettings{"MAX_LEASE_TIME_${itf}"} = '120'; - $dhcpsettings{"DOMAIN_NAME_${itf}"} = $mainsettings{'DOMAINNAME'}; + $newsort .= $rev; } - } - $dhcpsettings{'FIX_ENABLED'} = 'on'; + $dhcpsettings{'SORT_FIXEDLEASELIST'} = $newsort; + &writeconfig(0); + &writefixedleases(0); } -&Header::openpage($Lang::tr{'dhcp configuration'}, 1, ''); -&Header::openbigbox('100%', 'left', '', $errormessage); -if ($errormessage) { - &Header::openbox('100%', 'left', "$Lang::tr{'error messages'}:", 'error'); - print "<font class='base'>$errormessage </font>\n"; - &Header::closebox(); +# +# display box with errormessage in case of error +# +if ( $errormessage ) +{ + &Header::openbox('100%', 'left', "$Lang::tr{'error messages'}:", 'error'); + print "<font class='base'>$errormessage </font>\n"; + &Header::closebox(); } -if ($warnNTPmessage) { - $warnNTPmessage = "<font color=${Header::colourred}><b>$Lang::tr{'capswarning'}</b></font>: $warnNTPmessage"; -} -&Header::openbox('100%', 'left', 'DHCP', $error_dhcp); -print "<form method='post' action='$ENV{'SCRIPT_NAME'}'>"; -foreach my $itf (@ITFs) { - my %checked=(); - $checked{'ENABLE'}{'on'} = ( $dhcpsettings{"ENABLE_${itf}"} ne 'on') ? '' : "checked='checked'"; - $checked{'ENABLEBOOTP'}{'on'} = ( $dhcpsettings{"ENABLEBOOTP_${itf}"} ne 'on') ? '' : "checked='checked'"; - $checked{'ENABLEHOSTNAMES'}{'on'} = ( $dhcpsettings{"ENABLEHOSTNAMES_${itf}"} ne 'on') ? '' : "checked='checked'"; +# +# display box with main settings +# +&Header::openbox('100%', 'left', 'DHCP', $error_save_main); +print "<form method='post' name='frm_main' action='$ENV{'SCRIPT_NAME'}'>"; +foreach my $interface (@INTERFACEs) +{ +for ($counter = 1; $counter <= $netsettings{"${interface}_COUNT"}; $counter++) +{ + my $lc_interface = lc($interface); + $checked{'ENABLE'}{'on'} = ( $dhcpsettings{"ENABLED_${interface}_${counter}"} ne 'on') ? '' : "checked='checked'"; + my $disable_text = ''; + $disable_text = "disabled='disabled'" if ( $disable_main == 1 ); - if ($netsettings{"${itf}_DEV"} ne '' ) { # Show only defined interface - my $lc_itf=lc($itf); print <<END <table width='100%'> <tr> - <td width='25%' class='boldbase'><b><font color='${lc_itf}'>$Lang::tr{"$lc_itf interface"}</font></b></td> - <td class='base'>$Lang::tr{'enabled'}: - <input type='checkbox' name='ENABLE_${itf}' $checked{'ENABLE'}{'on'} /></td> - <td width='25%' class='base'>$Lang::tr{'ip address'}/$Lang::tr{'netmask'}:</td><td><b>$netsettings{"${itf}_ADDRESS"}/$netsettings{"${itf}_NETMASK"}</b></td> + <td width='25%' class='boldbase'><span class='ipcop_iface_$lc_interface'><b>$Lang::tr{"$lc_interface"}</b></span></td> + <td width='25%' class='base'>$Lang::tr{'enabled'}:<input type='checkbox' name='ENABLED_${interface}_${counter}' $checked{'ENABLE'}{'on'} $disable_text /></td> + <td width='25%' class='base'>$Lang::tr{'ip address'}/$Lang::tr{'netmask'}:</td> + <td width='25%' class='base'><b>$netsettings{"${interface}_${counter}_ADDRESS"}/$netsettings{"${interface}_${counter}_NETMASK"}</b></td> +</tr> +END +; +if ( $disable_main == 0 ) +{ +print <<END + <tr> + <td width='25%' class='base'>$Lang::tr{'start address'}: <img src='/blob.gif' alt='*' /></td> + <td width='25%'><input type='text' name='START_ADDR_${interface}_${counter}' value='$dhcpsettings{"START_ADDR_${interface}_${counter}"}' /></td> + <td width='25%' class='base'>$Lang::tr{'end address'}: <img src='/blob.gif' alt='*' /></td> + <td width='25%'><input type='text' name='END_ADDR_${interface}_${counter}' value='$dhcpsettings{"END_ADDR_${interface}_${counter}"}' /></td> </tr><tr> - <td width='25%' class='base'>$Lang::tr{'start address'}: <img src='/blob.gif' alt='*' /></td> - <td width='25%'><input type='text' name='START_ADDR_${itf}' value='$dhcpsettings{"START_ADDR_${itf}"}' /></td> - <td width='25%' class='base'>$Lang::tr{'end address'}: <img src='/blob.gif' alt='*' /></td> - <td width='25%'><input type='text' name='END_ADDR_${itf}' value='$dhcpsettings{"END_ADDR_${itf}"}' /></td> + <td class='base'>$Lang::tr{'default lease time'}:</td> + <td><input type='text' name='DEFAULT_LEASE_TIME_${interface}_${counter}' value='$dhcpsettings{"DEFAULT_LEASE_TIME_${interface}_${counter}"}' size='5' /></td> + <td class='base'>$Lang::tr{'domain name suffix'}: <img src='/blob.gif' alt='*' /></td> + <td><input type='text' name='DOMAIN_NAME_${interface}_${counter}' value='$dhcpsettings{"DOMAIN_NAME_${interface}_${counter}"}' /></td> +<!-- </tr><tr> + <td>$Lang::tr{'dhcp allow bootp'}:</td> + <td><input type='checkbox' name='ENABLED_BOOTP_${interface}_${counter}' $checked{'ENABLED_BOOTP_${interface}_${counter}'}{'on'} /></td> + <td> </td><td> </td> --> </tr><tr> - <td class='base'>$Lang::tr{'default lease time'}:</td> - <td><input type='text' name='DEFAULT_LEASE_TIME_${itf}' value='$dhcpsettings{"DEFAULT_LEASE_TIME_${itf}"}' size='5' /></td> - <td class='base'>$Lang::tr{'max lease time'}:</td> - <td><input type='text' name='MAX_LEASE_TIME_${itf}' value='$dhcpsettings{"MAX_LEASE_TIME_${itf}"}' size='5' /></td> + <td class='base'>$Lang::tr{'primary dns'}:</td> + <td><input type='text' name='DNS1_${interface}_${counter}' value='$dhcpsettings{"DNS1_${interface}_${counter}"}' /></td> + <td class='base'>$Lang::tr{'secondary dns'}: <img src='/blob.gif' alt='*' /></td> + <td><input type='text' name='DNS2_${interface}_${counter}' value='$dhcpsettings{"DNS2_${interface}_${counter}"}' /></td> </tr><tr> - <td class='base'>$Lang::tr{'dhcp base ip fixed lease'}: <img src='/blob.gif' alt='*' /></td> - <td><input type='text' name='BASE_IP_FIXED_LEASE_${itf}' value='$dhcpsettings{"BASE_IP_FIXED_LEASE_${itf}"}' /></td> + <td class='base'>$Lang::tr{'primary ntp server'}: <img src='/blob.gif' alt='*' /></td> + <td><input type='text' name='NTP1_${interface}_${counter}' value='$dhcpsettings{"NTP1_${interface}_${counter}"}' /></td> + <td class='base'>$Lang::tr{'secondary ntp server'}: <img src='/blob.gif' alt='*' /></td> + <td><input type='text' name='NTP2_${interface}_${counter}' value='$dhcpsettings{"NTP2_${interface}_${counter}"}' /></td> </tr><tr> - <td class='base'>$Lang::tr{'domain name suffix'}: <img src='/blob.gif' alt='*' /></td> - <td><input type='text' name='DOMAIN_NAME_${itf}' value='$dhcpsettings{"DOMAIN_NAME_${itf}"}' /></td> - <td>$Lang::tr{'dhcp allow bootp'}:</td> - <td><input type='checkbox' name='ENABLEBOOTP_${itf}' $checked{'ENABLEBOOTP'}{'on'} /></td> -</tr><tr> - <td>$Lang::tr{'allow lease hostnames'}:</td> - <td><input type='checkbox' name='ENABLEHOSTNAMES_${itf}' $checked{'ENABLEHOSTNAMES'}{'on'} /></td> - <td class='base'>$Lang::tr{'nis domain'}</td> - <td><input type='text' name='NIS_${itf}' value='$dhcpsettings{"NIS_${itf}"}' /></td> -</tr><tr> - <td class='base'>$Lang::tr{'primary dns'}:</td> - <td><input type='text' name='DNS1_${itf}' value='$dhcpsettings{"DNS1_${itf}"}' /></td> - <td class='base'>$Lang::tr{'secondary dns'}: <img src='/blob.gif' alt='*' /></td> - <td><input type='text' name='DNS2_${itf}' value='$dhcpsettings{"DNS2_${itf}"}' /></td> -</tr><tr> - <td class='base'>$Lang::tr{'primary ntp server'}: <img src='/blob.gif' alt='*' /></td> - <td><input type='text' name='NTP1_${itf}' value='$dhcpsettings{"NTP1_${itf}"}' /></td> - <td class='base'>$Lang::tr{'secondary ntp server'}: <img src='/blob.gif' alt='*' /></td> - <td><input type='text' name='NTP2_${itf}' value='$dhcpsettings{"NTP2_${itf}"}' /></td> -</tr><tr> - <td class='base'>$Lang::tr{'primary wins server address'}: <img src='/blob.gif' alt='*' /></td> - <td><input type='text' name='WINS1_${itf}' value='$dhcpsettings{"WINS1_${itf}"}' /></td> - <td class='base'>$Lang::tr{'secondary wins server address'}: <img src='/blob.gif' alt='*' /></td> - <td><input type='text' name='WINS2_${itf}' value='$dhcpsettings{"WINS2_${itf}"}' /></td> + <td class='base'>$Lang::tr{'primary wins server address'}: <img src='/blob.gif' alt='*' /></td> + <td><input type='text' name='WINS1_${interface}_${counter}' value='$dhcpsettings{"WINS1_${interface}_${counter}"}' /></td> + <td class='base'>$Lang::tr{'secondary wins server address'}: <img src='/blob.gif' alt='*' /></td> + <td><input type='text' name='WINS2_${interface}_${counter}' value='$dhcpsettings{"WINS2_${interface}_${counter}"}' /></td> </tr> -</table> -<hr /> END ; - }# Show only defined interface -}#foreach itf -print <<END -<table width='100%'> -<tr> - <td class='base' width='25%'><img src='/blob.gif' align='top' alt='*' /> $Lang::tr{'this field may be blank'}</td> - <td class='base' width='30%'>$warnNTPmessage</td> - <td width='40%' align='center'><input type='submit' name='ACTION' value='$Lang::tr{'save'}' /></td> - <td width='5%' align='right'> - <a href='${General::adminmanualurl}/services.html#services_dhcp' target='_blank'> - <img src='/images/web-support.png' alt='$Lang::tr{'online help en'}' title='$Lang::tr{'online help en'}' /></a></td> -</tr> -</table> -</form> -END -; - -&Header::closebox(); - -if ($warnmessage) { - $warnmessage = "<font color=${Header::colourred}><b>$Lang::tr{'capswarning'}</b></font>: $warnmessage"; } -$errormessage = &DhcpCheckSyntax; -if ($errormessage) { - &Header::openbox('100%', 'left', "$Lang::tr{'error messages'}:"); - print "<font class='base'>$errormessage </font>\n"; - &Header::closebox(); +print "</table><hr />"; } - -&Header::openbox('100%', 'left', $Lang::tr{'dhcp advopt list'}); -# DHCP Advanced options settings -my %checked=(); -$checked{'ADVOPT_ENABLED'}{'on'} = ($dhcpsettings{'ADVOPT_ENABLED'} ne 'on') ? '' : "checked='checked'"; - -print "<form method='post' action='$ENV{'SCRIPT_NAME'}'><table width='100%'>"; -my $buttontext = $Lang::tr{'add'}; -if ($dhcpsettings{'KEY1'} ne '') { - $buttontext = $Lang::tr{'update'}; - print "<tr><td class='boldbase'><b>$Lang::tr{'dhcp advopt edit'}</b></td></tr>"; -} else { - print "<tr><td class='boldbase'><b>$Lang::tr{'dhcp advopt add'}</b></td></tr>" } -#search if the 'option' is in the list and print the syntax model -my $opt = `/bin/grep "^option $dhcpsettings{'ADVOPT_NAME'} " $filename3`; -if ($opt ne '') { - $opt =~ s/option $dhcpsettings{'ADVOPT_NAME'}/Syntax:/; # "option xyz abc" => "syntax: abc" - $opt =~ s/;//; - #$opt = "<tr><td></td><td></td><td colspan='2'>$opt</td></tr>"; +if ( $disable_main == 1 ) +{ + print "</form>"; } -my $listopt = &SelectKnownOptions('ADVOPT_LIST'); -print <<END -<tr> - <td class='base'>$Lang::tr{'dhcp advopt name'}:</td> - <td colspan='2'><input type='text' name='ADVOPT_NAME' value='$dhcpsettings{'ADVOPT_NAME'}' size='18' /> $Lang::tr{'or'} $Lang::tr{'select'} $listopt</td> -</tr><tr> - <td class='base'>$Lang::tr{'dhcp advopt value'}:</td> - <td><input type='text' name='ADVOPT_DATA' value='$dhcpsettings{'ADVOPT_DATA'}' size='60' /> $opt</td> -</tr><tr> - <td class='base'>$Lang::tr{'enabled'}:<input type='checkbox' name='ADVOPT_ENABLED' $checked{'ADVOPT_ENABLED'}{'on'} /></td> - <td class='base'>$Lang::tr{'dhcp advopt scope'}: <img src='/blob.gif' alt='*' /> - -END -; - -# Put a checkbox for each interface. Checkbox visible disabled if interface is disabled -foreach my $itf (@ITFs) { - my $lc_itf=lc($itf); - $checked{'ADVOPT_SCOPE_${itf}'}{'on'} = $dhcpsettings{"ADVOPT_SCOPE_${itf}"} ne 'on' ? '' : "checked='checked'"; - print "$Lang::tr{\"${lc_itf}\"} <input type='checkbox' name='ADVOPT_SCOPE_${itf}' $checked{'ADVOPT_SCOPE_${itf}'}{'on'} "; - print $dhcpsettings{"ENABLE_${itf}"} eq 'on' ? "/>" : "disabled='disabled' />"; - print " "; -} - -print <<END - </td> -</tr> -</table> -<hr /> +else +{ + print <<END <table width='100%'> <tr> - <td class='base' width='35%'><img src='/blob.gif' align='top' alt='*' /> $Lang::tr{'dhcp advopt scope help'}</td> - <td class='base' width='25%'>$warnmessage</td> - <td width='40%' align='center'> - <input type='hidden' name='ACTION' value='$Lang::tr{'add'}1' /> - <input type='submit' name='SUBMIT' value='$buttontext' /> - <input type='submit' name='SUBMIT' value='$Lang::tr{'dhcp advopt help'}' /> - <input type='hidden' name='KEY1' value='$dhcpsettings{'KEY1'}' /> - </td> + <td class='base' width='55%'><img src='/blob.gif' align='top' alt='*' /> $Lang::tr{'this field may be blank'}</td> + <td width='40%' align='center'><input type='hidden' name='ACTION' value='SAVE_MAIN' /><input type='submit' name='SUBMIT' value='$Lang::tr{'save'}' /></td> + <td width='5%' align='right'> + <a href='${General::adminmanualurl}/services.html#services_dhcp' target='_blank'> + <img src='/images/web-support.png' alt='$Lang::tr{'online help en'}' title='$Lang::tr{'online help en'}' /></a></td> </tr> </table> </form> END ; -#Edited line number (KEY1) passed until cleared by 'save' or 'remove' or 'new sort order' - -# print help taken from the file describing options -if ($dhcpsettings{'SUBMIT'} eq $Lang::tr{'dhcp advopt help'}) { - print "<hr />"; - print "<table width='100%'>"; - print "<tr><td width='30%'><b>$Lang::tr{'dhcp advopt name'}</b></td><td width='70%'><b>$Lang::tr{'dhcp advopt value'}</b></td>"; - open(FILE, "$filename3"); - my @current3 = <FILE>; - close(FILE); - foreach my $line (@current3) { - $line =~ /option ([a-z0-9-]+) (.*);/; - print "<tr><td>$1</td><td>$2</td></tr>\n"; - } - print "<tr><td colspan='2'><hr /></td></tr>\n"; - print '<tr><td>string type</td><td>"quoted string" or 00:01:FF...</td></tr>'; - print '<tr><td>text type</td><td>"quoted text only"</td></tr>'; - print '<tr><td>ip-address type </td><td>10.0.0.1 | www.dot.com</td></tr>'; - print '<tr><td>int,uint types</td><td>numbers</td></tr>'; - print '<tr><td>flag type</td><td>on | off</td></tr>'; - print '<tr><td>boolean type</td><td>on|true | off|false</td></tr>'; - print '</table>'; - print "<hr />"; - print "<table width='100%'>"; - print "<tr><td width='30%'><b>$Lang::tr{'dhcp advopt custom definition'}</b></td><td width='70%'><b>$Lang::tr{'dhcp advopt value'}</b></td>"; - print "<tr><td>any-name </td><td> code NNN=$OptionTypes</td></tr>"; - print '<tr><td>a-string</td><td>code 100=string</td></tr>'; - print '<tr><td>a-number</td><td>code 101=signed integer 8</td></tr>'; - print '<tr><td>an-array</td><td>code 102=array of "one basic type", except text&string</td></tr>'; - print '<tr><td>a-record</td><td>code 103={any,number,of,basics,types}</td></tr>'; - print '<tr><td>an-array-of-record</td><td>code 104=array of {any,number,of,basics,types}</td></tr>'; - print '<tr><td>wpad</td><td>code 252=text</td></tr>'; - print '<tr><td>wpad</td><td>"http://www.server.fr/path-to/proxy.pac"</td></tr>'; - print '<tr><td>myopt</td><td>code 152=array of {integer 16,boolean}</td></tr>'; - print '<tr><td>myopt</td><td>8 false, 0 true, 7 false</td></tr>'; - print '</table>'; } +&Header::closebox(); -print <<END -<hr /> -<table width='100%'> -<tr> - <td width='30%' class='boldbase' align='center'><b>$Lang::tr{'dhcp advopt name'}</b></td> - <td width='50%' class='boldbase' align='center'><b>$Lang::tr{'dhcp advopt value'}</b></td> - <td width='20%' class='boldbase' align='center'><b>$Lang::tr{'dhcp advopt scope'}</b></td> - <td colspan='3' class='boldbase' align='center'><b>$Lang::tr{'action'}</b></td> -</tr> -END -; -my $key = 0; -foreach my $line (@current1) { - my $gif = ''; - my $gdesc = ''; - chomp($line); # remove newline - my @temp = split(/\t/,$line); - if ($temp[0] eq "on") { - $gif = 'on.gif'; - $gdesc = $Lang::tr{'click to disable'}; - } else { - $gif = 'off.gif'; - $gdesc = $Lang::tr{'click to enable'}; - } +# +# display box with fixed leases +# +&Header::openbox('100%', 'left', $Lang::tr{'current fixed leases'}, $error_save_fixed); - if ($dhcpsettings{'KEY1'} eq $key) { - print "<tr bgcolor='${Header::colouryellow}'>"; - } elsif ($key % 2) { - print "<tr bgcolor='${Header::table2colour}'>"; - } else { - print "<tr bgcolor='${Header::table1colour}'>"; - } +if ( $disable_fixed == 0 ) +{ + $checked{'FIXED_ENABLED'}{'on'} = ($dhcpsettings{'FIXED_ENABLED'} ne 'on') ? '' : "checked='checked'"; + my $action_text = $Lang::tr{'add new lease'}; + # if KEY_FIXED is set, this is edit/update not add - print <<END -<td align='center'>$temp[1]</td> -<td align='center'>$temp[2]</td> -<td align='center'> -END -; - # Prepare a global flag to make easy reading - my $global = ''; - my $disabledTogle = ''; - my $disabledEditRemove = ''; - if ( ExistNewOptionDefinition ($temp[1] . ' ' . $temp[2]) ) { - $global = $Lang::tr{'dhcp advopt defin... [truncated message content] |