#!/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;
require '/var/ipfire/general-functions.pl';
require "${General::swroot}/lang.pl";
require "${General::swroot}/header.pl";
my %netsettings=();
&General::readhash("${General::swroot}/ethernet/settings", \%netsettings);
my @networks=();
my $filename = "${General::swroot}/firewall/customnetworks";
&setup_default_networks();
&Header::getcgihash(\%cgiparams);
if ($cgiparams{'ACTION'} eq $Lang::tr{'add'}){
&validateparams();
unless($errormessage){
$key++; # Add one to last sequence number
open(FILE,">>$filename") or die 'Unable to open custom networks file.';
flock FILE, 2;
print FILE "$key,$cgiparams{'NAME'},$cgiparams{'IPADDRESS'},$cgiparams{'NETMASK'}\n";
close(FILE);
&General::log("$Lang::tr{'network added'}: $cgiparams{'NAME'}");
undef %cgiparams;
}
}
if ($cgiparams{'ACTION'} eq $Lang::tr{'update'})
{
&validateparams();
# Darren Critchley - If there is an error don't waste any more processing time
if ($errormessage) { $cgiparams{'ACTION'} = $Lang::tr{'edit'}; goto UPD_ERROR; }
unless($errormessage){
open(FILE, $filename) or die 'Unable to open custom networks file.';
my @current = ;
close(FILE);
open(FILE, ">$filename") or die 'Unable to open config file.';
flock FILE, 2;
foreach my $line (@current) {
chomp($line);
my @temp = split(/\,/,$line);
if ($cgiparams{'KEY'} eq $temp[0]) {
print FILE "$cgiparams{'KEY'},$cgiparams{'NAME'},$cgiparams{'IPADDRESS'},$cgiparams{'NETMASK'}\n";
} else {
print FILE "$line\n";
}
}
close(FILE);
&General::log("$Lang::tr{'network updated'}: $cgiparams{'NAME'}");
undef %cgiparams;
}
UPD_ERROR:
}
if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'})
{
open(FILE, "$filename") or die 'Unable to open custom networks file.';
my @current = ;
close(FILE);
unless ($errormessage)
{
foreach my $line (@current)
{
chomp($line);
my @temp = split(/\,/,$line);
if ($cgiparams{'KEY'} eq $temp[0]) {
$cgiparams{'NAME'} = $temp[1];
$cgiparams{'IPADDRESS'} = $temp[2];
$cgiparams{'NETMASK'} = $temp[3];
}
}
}
}
if ($cgiparams{'ACTION'} eq $Lang::tr{'remove'})
{
open(FILE, $filename) or die 'Unable to open custom networks file.';
my @current = ;
close(FILE);
open(FILE, ">$filename") or die 'Unable to open custom networks file.';
flock FILE, 2;
foreach my $line (@current)
{
chomp($line);
if ($line ne '') {
my @temp = split(/\,/,$line);
if ($cgiparams{'KEY'} eq $temp[0]) {
&General::log("$Lang::tr{'network removed'}: $temp[1]");
} else {
print FILE "$temp[0],$temp[1],$temp[2],$temp[3]\n";
}
}
}
close(FILE);
undef %cgiparams;
}
if ($cgiparams{'ACTION'} eq $Lang::tr{'reset'})
{
undef %cgiparams;
}
if ($cgiparams{'ACTION'} eq '')
{
$cgiparams{'KEY'} = '';
$cgiparams{'IPADDRESS'} = '';
$cgiparams{'NETMASK'} = '';
$cgiparams{'NAME'} = '';
}
&Header::showhttpheaders();
&Header::openpage($Lang::tr{'networks settings'}, 1, '');
&Header::openbigbox('100%', 'LEFT', '', $errormessage);
# DEBUG DEBUG
#&Header::openbox('100%', 'LEFT', 'DEBUG');
#foreach $line (keys %cgiparams) {
# print "$line = $cgiparams{$line} ";
#}
#print "$ENV{'QUERY_STRING'}\n";
#print " \n";
#&Header::closebox();
if ($errormessage) {
&Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
print "$errormessage\n";
print " \n";
&Header::closebox();
}
if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){
&Header::openbox('100%', 'LEFT', "$Lang::tr{'edit network'}:");
} else {
&Header::openbox('100%', 'LEFT', "$Lang::tr{'add network'}:");
}
print <
$Lang::tr{'name'}
$Lang::tr{'ip address'}
$Lang::tr{'netmask'}
END
;
if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){
# Darren Critchley - put in next release - author has authorized GPL inclusion
# print "
END
;
&Header::closebox();
&Header::openbox('100%', 'LEFT', "$Lang::tr{'custom networks'}:");
print <
$Lang::tr{'name'}
$Lang::tr{'ip address'}
$Lang::tr{'netmask'}
END
;
&display_custom_networks();
print <
END
;
&Header::closebox();
&Header::openbox('100%', 'LEFT', "$Lang::tr{'default networks'}:");
print <
$Lang::tr{'name'}
$Lang::tr{'ip address'}
$Lang::tr{'netmask'}
END
;
&display_default_networks();
print <
END
;
&Header::closebox();
print "$Lang::tr{'this feature has been sponsored by'} : ";
print "Kobelt Development Inc..\n";
&Header::closebigbox();
&Header::closepage();
sub display_custom_networks
{
open(FILE, "$filename") or die 'Unable to open networks file.';
my @current = ;
close(FILE);
my $id = 0;
foreach $line (@current)
{
chomp($line);
if ($line ne ''){
my @temp = split(/\,/,$line);
# Darren Critchley highlight the row we are editing
if ( $cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'KEY'} eq $temp[0] ) {
print "
\n";
} else {
if ($id % 2) {
print "
\n";
} else {
print "
\n";
}
}
print "
$temp[1]
\n";
print "
$temp[2]
\n";
print "
$temp[3]
\n";
print <
END
;
print "
\n";
$id++;
}
}
}
sub display_default_networks
{
foreach $line (sort @networks)
{
my @temp = split(/\,/,$line);
if ($id % 2) {
print "
\n";
} else {
print "
\n";
}
print "
$temp[0]
\n";
print "
$temp[1]
\n";
print "
$temp[2]
\n";
print "
\n";
$id++;
}
}
sub setup_default_networks
{
# Get current defined networks (Red, Green, Blue, Orange)
my $line = "Any,0.0.0.0,0.0.0.0";
push (@networks, $line);
$line = "localhost,127.0.0.1,255.255.255.255";
push (@networks, $line);
$line = "localnet,127.0.0.0,255.0.0.0";
push (@networks, $line);
$line = "Private Network 10.0.0.0,10.0.0.0,255.0.0.0";
push (@networks, $line);
$line = "Private Network 172.16.0.0,172.16.0.0,255.240.0.0";
push (@networks, $line);
$line = "Private Network 192.168.0.0,192.168.0.0,255.255.0.0";
push (@networks, $line);
my $red_address=`cat ${General::swroot}/red/local-ipaddress`;
$line = "Red Address,$red_address,";
push (@networks, $line);
$line = "Green Address,$netsettings{'GREEN_ADDRESS'},255.255.255.255";
push (@networks, $line);
$line = "Green Network,$netsettings{'GREEN_NETADDRESS'},$netsettings{'GREEN_NETMASK'}";
push (@networks, $line);
if ($netsettings{'ORANGE_DEV'}ne ''){
$line = "Orange Address,$netsettings{'ORANGE_ADDRESS'},255.255.255.255";
push (@networks, $line);
$line = "Orange Network,$netsettings{'ORANGE_NETADDRESS'},$netsettings{'ORANGE_NETMASK'}";
push (@networks, $line);
}
if ($netsettings{'BLUE_DEV'}ne ''){
$line = "Blue Address,$netsettings{'BLUE_ADDRESS'},255.255.255.255";
push (@networks, $line);
$line = "Blue Network,$netsettings{'BLUE_NETADDRESS'},$netsettings{'BLUE_NETMASK'}";
push (@networks, $line);
}
open(FILE, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
my @current = ;
close(FILE);
my $ctr = 0;
foreach my $lne (@current)
{
if ($lne ne ''){
chomp($lne);
my @temp = split(/\,/,$lne);
if ($temp[2] eq '') {
$temp[2] = "Alias $ctr : $temp[0]";
}
$line = "$temp[2],$temp[0],";
push (@networks, $line);
$ctr++;
}
}
}
# Validate Field Entries
sub validateparams
{
if ($cgiparams{'NAME'} eq '') {
$errormessage = $Lang::tr{'nonetworkname'};
return;
}
$cgiparams{'NAME'}=&Header::cleanhtml($cgiparams{'NAME'});
unless(&General::validip($cgiparams{'IPADDRESS'})){$errormessage = $Lang::tr{'invalid ip'}; }
unless($errormessage){
my @tmp = split(/\./,$cgiparams{'IPADDRESS'});
if ($cgiparams{'NETMASK'} eq '' && $tmp[3] ne '255' && $tmp[3] ne '0'){
$cgiparams{'NETMASK'} = "255.255.255.255";
}
}
unless(&General::validmask($cgiparams{'NETMASK'})){$errormessage = $Lang::tr{'subnet is invalid'}; }
open(FILE, $filename) or die 'Unable to open custom network file.';
my @current = ;
close(FILE);
foreach my $line (@current)
{
chomp($line);
if ($line ne '') {
my @temp = split(/\,/,$line);
if ($cgiparams{'NAME'} eq $temp[1] && $cgiparams{'KEY'} ne $temp[0]) {
$errormessage=$Lang::tr{'duplicate name'};
return;
}
$key=$temp[0];
}
}
foreach $line (@networks)
{
my @temp = split(/\,/,$line);
if ($cgiparams{'NAME'} eq $temp[0]) {
$errormessage=$Lang::tr{'duplicate name'};
return;
}
}
}