#!/usr/bin/perl
###############################################################################
# #
# IPFire.org - A linux based firewall #
# Copyright (C) 2007 Michael Tremer & Christian Schmidt #
# #
# This program 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 3 of the License, or #
# (at your option) any later version. #
# #
# This program 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. #
# #
# You should have received a copy of the GNU General Public License #
# along with this program. If not, see . #
# #
###############################################################################
use strict;
use experimental 'smartmatch';
# enable only the following on debugging purpose
#use warnings;
#use CGI::Carp 'fatalsToBrowser';
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
#workaround to suppress a warning when a variable is used only once
my @dummy = ( ${Header::colouryellow} );
undef (@dummy);
our %dhcpsettings=();
our %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 standart)
# because we need commas in the some data
our $filename2 = "${General::swroot}/dhcp/fixleases";
our $filename3 = "${General::swroot}/dhcp/advoptions-list"; # Describe the allowed syntax for dhcp options
my $errormessage = '';
my $warnNTPmessage = '';
my @nosaved=();
my %color = ();
#Basic syntax allowed for new Option definition. Not implemented: RECORDS & array of RECORDS
our $OptionTypes = 'boolean|((un)?signed )?integer (8|16|32)|ip-address|text|string|encapsulate \w+|array of ip-address';
&Header::showhttpheaders();
our @ITFs=('GREEN');
if (&Header::blue_used()){push(@ITFs,'BLUE');}
#Settings1 for the first screen box
foreach my $itf (@ITFs) {
$dhcpsettings{"ENABLE_${itf}"} = 'off';
$dhcpsettings{"ENABLEBOOTP_${itf}"} = 'off';
$dhcpsettings{"START_ADDR_${itf}"} = '';
$dhcpsettings{"END_ADDR_${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{"NEXT_${itf}"} = '';
$dhcpsettings{"FILE_${itf}"} = '';
$dhcpsettings{"DNS_UPDATE_KEY_NAME_${itf}"} = '';
$dhcpsettings{"DNS_UPDATE_KEY_SECRET_${itf}"} = '';
$dhcpsettings{"DNS_UPDATE_KEY_ALGO_${itf}"} = '';
$dhcpsettings{"DENY_KNOWN_CLIENTS_${itf}"} = 'off';
}
$dhcpsettings{'SORT_FLEASELIST'} = 'FIPADDR';
$dhcpsettings{'SORT_LEASELIST'} = 'IPADDR';
# DNS Update settings
$dhcpsettings{'DNS_UPDATE_ENABLED'} = 'off';
#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{'ACTION'} = '';
$dhcpsettings{'KEY1'} = '';
$dhcpsettings{'KEY2'} = '';
@nosaved=('FIX_MAC','FIX_ADDR','FIX_ENABLED','FIX_NEXTADDR',
'FIX_FILENAME','FIX_ROOTPATH','FIX_REMARK');
$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 Ipcop settings
&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
&General::readhash("${General::swroot}/main/settings", \%mainsettings);
&General::readhash("${General::swroot}/time/settings", \%timesettings);
&General::readhash("/srv/web/ipfire/html/themes/".$mainsettings{'THEME'}."/include/colors.txt", \%color);
#Get GUI values
&Header::getcgihash(\%dhcpsettings);
open(FILE, "$filename1") or die 'Unable to open dhcp advanced options file.';
our @current1 = ;
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]);
}
open(FILE, "$filename2") or die 'Unable to open fixed leases file.';
our @current2 = ;
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{"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}"});
}
}
if (!($dhcpsettings{"DEFAULT_LEASE_TIME_${itf}"} =~ /^\d+$/)) {
$errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid default lease time'} . $dhcpsettings{'DEFAULT_LEASE_TIME_${itf}'};
goto ERROR;
}
if (!($dhcpsettings{"MAX_LEASE_TIME_${itf}"} =~ /^\d+$/)) {
$errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid max lease time'} . $dhcpsettings{'MAX_LEASE_TIME_${itf}'};
goto ERROR;
}
if ($dhcpsettings{"DNS1_${itf}"}) {
if (!(&General::validip($dhcpsettings{"DNS1_${itf}"}))) {
$errormessage = "DHCP on ${itf}: " . $Lang::tr{'invalid primary dns'};
goto ERROR;
}
}
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{"NEXT_${itf}"}) {
if (!(&General::validip($dhcpsettings{"NEXT_${itf}"}))) {
$errormessage = "next-server on ${itf}: " . $Lang::tr{'invalid ip'};
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{'ENABLECLNTP'} 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{'ENABLECLNTP'} 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','q'); # 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
} else {
&General::readhash($setting, \%dhcpsettings); # Get saved settings and reset to good if needed
}
## 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', 'q'); # 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
}
#Sorting of allocated leases
&Header::CheckSortOrder;
## Now manipulate the two multi-line list with Settings2.
# '1' suffix is for ADVANCED OPTIONS
# '2' suffix is for FIXED LEASES
# Toggle enable/disable field on specified options.
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);
#Write changes to dhcpd.conf.
&buildconf;
}
if ($dhcpsettings{'ACTION'} eq $Lang::tr{'add'}.'1' &&
$dhcpsettings{'SUBMIT'} ne $Lang::tr{'dhcp advopt help'}) {
$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 !
if ($dhcpsettings{'ADVOPT_DATA'} eq '') {
$errormessage=$Lang::tr{'dhcp advopt blank value'};
}
# 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
} elsif (! `grep "\$option $dhcpsettings{'ADVOPT_NAME'} " $filename3`) {
$errormessage=$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 ($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
{
$dhcpsettings{"ADVOPT_SCOPE_${itf}"} = 'on';
}
}
}
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') {
$dhcpsettings{'FIX_MAC'} =~ tr/-/:/;
unless(&General::validip($dhcpsettings{'FIX_ADDR'})) { $errormessage = $Lang::tr{'invalid fixed ip address'}; }
unless(&General::validmac($dhcpsettings{'FIX_MAC'})) { $errormessage = $Lang::tr{'invalid fixed mac address'}; }
if ($dhcpsettings{'FIX_NEXTADDR'}) {
unless(&General::validip($dhcpsettings{'FIX_NEXTADDR'})) { $errormessage = $Lang::tr{'invalid fixed ip address'}; }
}
my $key = 0;
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++;
}
unless ($errormessage) {
$dhcpsettings{'FIX_REMARK'} = &Header::cleanhtml($dhcpsettings{'FIX_REMARK'});
$dhcpsettings{'FIX_NEXTADDR'} = &Header::cleanhtml($dhcpsettings{'FIX_NEXTADDR'});
$dhcpsettings{'FIX_FILENAME'} = &Header::cleanhtml($dhcpsettings{'FIX_FILENAME'});
$dhcpsettings{'FIX_ROOTPATH'} = &Header::cleanhtml($dhcpsettings{'FIX_ROOTPATH'});
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'}\n");
open(FILE, ">$filename2") or die 'Unable to open fixed lease file.';
print FILE @current2;
close(FILE);
&General::log($Lang::tr{'fixed ip lease added'});
# Enter edit mode
$dhcpsettings{'KEY2'} = 0;
} 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'}\n";
$dhcpsettings{'KEY2'} = ''; # End edit mode
&General::log($Lang::tr{'fixed ip lease modified'});
# sort newly added/modified entry
&sortcurrent2;
}
#Write changes to dhcpd.conf.
&buildconf; # before calling buildconf which use fixed lease file !
}
}
if ($dhcpsettings{'ACTION_ALL'} eq '+') {
my $news = 0;
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;
if (!grep (/$2/,@current2)) {
unshift (@current2, "$mac,$ip,on,,,,imported\n");
$news++;
}
}
}
if ($news) {
#Write changes to dhcpd.conf.
$warnNTPmessage = $Lang::tr{'fixed ip lease added'}."($news)";
&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];
}
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'};
}
}
$dhcpsettings{'FIX_ENABLED'} = 'on';
}
&Header::openpage($Lang::tr{'dhcp configuration'}, 1, '');
&Header::openbigbox('100%', 'left', '', $errormessage);
if ($errormessage) {
&Header::openbox('100%', 'left', $Lang::tr{'error messages'});
print "$errormessage \n";
&Header::closebox();
}
if ($warnNTPmessage) {
$warnNTPmessage = "$Lang::tr{'capswarning'}: $warnNTPmessage";
}
&Header::openbox('100%', 'left', 'DHCP');
print "