]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - config/cfgroot/general-functions.pl
general-functions.pl: Add function to get full country name.
[ipfire-2.x.git] / config / cfgroot / general-functions.pl
index c592d5d0c2a28d56c8998eac80784b04022144d2..bd5ad0ac86aadc20a8eba574c07ec79a54fe2eba 100644 (file)
@@ -17,6 +17,7 @@ package General;
 use strict;
 use Socket;
 use IO::Socket;
+use Locale::Country;
 use Net::SSLeay;
 use Net::IPv4Addr qw(:all);
 $|=1; # line buffering
@@ -26,6 +27,8 @@ $General::swroot = 'CONFIG_ROOT';
 $General::noipprefix = 'noipg-';
 $General::adminmanualurl = 'http://wiki.ipfire.org';
 
+require "${General::swroot}/network-functions.pl";
+
 #
 # log ("message") use default 'ipcop' tag
 # log ("tag","message") use your tag
@@ -51,19 +54,23 @@ sub setup_default_networks
        $defaultNetworks->{$Lang::tr{'fwhost any'}}{'NAME'} = "ALL";
                
        $defaultNetworks->{$Lang::tr{'green'}}{'IPT'} = "$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}";
+       $defaultNetworks->{$Lang::tr{'green'}}{'NET'} = "$netsettings{'GREEN_ADDRESS'}";
        $defaultNetworks->{$Lang::tr{'green'}}{'NAME'} = "GREEN";
 
        if ($netsettings{'RED_DEV'} ne ''){
                $defaultNetworks->{$Lang::tr{'fwdfw red'}}{'IPT'} = "$netsettings{'RED_NETADDRESS'}/$netsettings{'RED_NETMASK'}";
+               $defaultNetworks->{$Lang::tr{'fwdfw red'}}{'NET'} = "$netsettings{'RED_ADDRESS'}";
                $defaultNetworks->{$Lang::tr{'fwdfw red'}}{'NAME'} = "RED";
        }
        if ($netsettings{'ORANGE_DEV'} ne ''){
                $defaultNetworks->{$Lang::tr{'orange'}}{'IPT'} = "$netsettings{'ORANGE_NETADDRESS'}/$netsettings{'ORANGE_NETMASK'}";
+               $defaultNetworks->{$Lang::tr{'orange'}}{'NET'} = "$netsettings{'ORANGE_ADDRESS'}";
                $defaultNetworks->{$Lang::tr{'orange'}}{'NAME'} = "ORANGE";
        }
 
        if ($netsettings{'BLUE_DEV'} ne ''){
                $defaultNetworks->{$Lang::tr{'blue'}}{'IPT'} = "$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}";
+               $defaultNetworks->{$Lang::tr{'blue'}}{'NET'} = "$netsettings{'BLUE_ADDRESS'}";
                $defaultNetworks->{$Lang::tr{'blue'}}{'NAME'} = "BLUE";
        }
        
@@ -96,8 +103,9 @@ sub setup_default_networks
                        my ($ip,$sub) = split(/\//,$ipsecsettings{'RW_NET'});
                        $sub=&General::iporsubtocidr($sub);
                        my @tempipsecsubnet = split("\/", $ipsecsettings{'RW_NET'});
-                       $defaultNetworks->{'IPsec RW ' .$ip."/".$sub}{'ADR'} = $tempipsecsubnet[0];
-                       $defaultNetworks->{'IPsec RW ' .$ip."/".$sub}{'NAME'} = "IPsec RW";
+                       $defaultNetworks->{'IPsec RW (' .$ip."/".$sub.")"}{'ADR'} = $tempipsecsubnet[0];
+                       $defaultNetworks->{'IPsec RW (' .$ip."/".$sub.")"}{'NAME'} = "IPsec RW";
+                       $defaultNetworks->{'IPsec RW (' .$ip."/".$sub.")"}{'NET'} = &getnextip($ip);
                }
        }
 }
@@ -118,6 +126,7 @@ sub get_aliases
                                $temp[2] = "Alias $ctr : $temp[0]";
                        }
                        $defaultNetworks->{$temp[2]}{'IPT'} = "$temp[0]";
+                       $defaultNetworks->{$temp[2]}{'NET'} = "$temp[0]";
                        
                        $ctr++;
                }
@@ -223,68 +232,36 @@ sub writehashpart
        close FILE;
 }
 
-sub age
-{
+sub age {
        my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
-               $atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];
-       my $now = time;
-       my $timestring = '';
-       my $dset = 0;           # Day is set, when > 0
-       my $hset = 0;           # Hour is set, when > 0
-       my $mset = 0;           # Minute is set, when > 0
-
-       my $totalsecs = $now - $mtime;
-       my $days = int($totalsecs / 86400);
-       my $totalhours = int($totalsecs / 3600);
-       my $hours = $totalhours % 24;
-       my $totalmins = int($totalsecs / 60);
-       my $mins = $totalmins % 60;
-       my $secs = $totalsecs % 60;
+               $atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];
+       my $totalsecs = time() - $mtime;
+       my @s = ();
 
-       if      ($days > 1) { 
-               ${timestring} .= ${days}.' '.$Lang::tr{'days'}.', ';
-               $dset = 1; 
-       }
-       elsif   ($days == 1) { 
-               ${timestring} .= ${days}.' '.$Lang::tr{'day'}.', ';
-               $dset = 1; 
+       my $secs = $totalsecs % 60;
+       $totalsecs /= 60;
+       if ($secs > 0) {
+               push(@s, "${secs}s");
        }
 
-       if      (($hours > 1) && !($dset)) { 
-               ${timestring} .= ${hours}.' '.$Lang::tr{'hours'}.', ';
-               $hset = 1;
-       }
-       elsif   (($hours == 1) && !($dset)) { 
-               ${timestring} .= ${hours}.' '.$Lang::tr{'hour'}.', ';
-               $hset = 1;
-       }
-       elsif ($dset) {
-               ${timestring} .= ${hours}.' '.$Lang::tr{'age shour'}.', ';
-               $hset = 1;
+       my $min = $totalsecs % 60;
+       $totalsecs /= 60;
+       if ($min > 0) {
+               push(@s, "${min}m");
        }
 
-       if      ((($mins > 1) || ($mins == 0)) && !($dset || $hset)) { 
-               ${timestring} .= ${mins}.' '.$Lang::tr{'minutes'}.', ';
-               $mset = 1;
-       }
-       elsif   (($mins == 1) && !($dset || $hset)) { 
-               ${timestring} .= ${mins}.' '.$Lang::tr{'minute'}.', ';
-               $mset = 1;
-       }
-       else {
-               ${timestring} .= ${mins}.' '.$Lang::tr{'age sminute'}.', '; 
-               $mset = 1;
+       my $hrs = $totalsecs % 24;
+       $totalsecs /= 24;
+       if ($hrs > 0) {
+               push(@s, "${hrs}h");
        }
 
-       if      ((($secs > 1) || ($secs == 0)) && !($dset || $hset || $mset)) { 
-               ${timestring} .= ${secs}.' '.$Lang::tr{'age seconds'};
-       }
-       elsif   (($secs == 1) && !($dset || $hset || $mset)) { 
-               ${timestring} .= $secs.' '.$Lang::tr{'age second'};
+       my $days = int($totalsecs);
+       if ($days > 0) {
+               push(@s, "${days}d");
        }
-       else    { ${timestring} .= $secs.' '.$Lang::tr{'age ssecond'}; }
 
-       return ${timestring};
+       return join(" ", reverse(@s));
 }
 
 sub validip
@@ -307,21 +284,10 @@ sub validip
        }
 }
 
-sub validmask
-{
-       my $mask = $_[0];
+sub validmask {
+       my $mask = shift;
 
-       # secord part an ip?
-       if (&validip($mask)) {
-               return 1; }
-       # second part a number?
-       if (/^0/) {
-               return 0; }
-       if (!($mask =~ /^\d+$/)) {
-               return 0; }
-       if ($mask >= 0 && $mask <= 32) {
-               return 1; }
-       return 0;
+       return &Network::check_netmask($mask) || &Network::check_prefix($mask);
 }
 
 sub validipormask
@@ -342,24 +308,12 @@ sub validipormask
        return &validmask($mask);
 }
 
-sub subtocidr
-{
-       #gets: Subnet in decimal (255.255.255.0) 
-       #Gives: 24 (The cidr of network)
-       my ($byte1, $byte2, $byte3, $byte4) = split(/\./, $_[0].".0.0.0.0"); 
-       my $num = ($byte1 * 16777216) + ($byte2 * 65536) + ($byte3 * 256) + $byte4; 
-       my $bin = unpack("B*", pack("N", $num)); 
-       my $count = ($bin =~ tr/1/1/); 
-       return $count;
+sub subtocidr {
+       return &Network::convert_netmask2prefix(shift);
 }
 
-sub cidrtosub
-{
-       #gets: Cidr of network (20-30 for ccd) 
-       #Konverts 30 to 255.255.255.252 e.g
-       my $cidr=$_[0];
-    my $netmask = &Net::IPv4Addr::ipv4_cidr2msk($cidr);
-    return "$netmask";
+sub cidrtosub {
+       return &Network::convert_prefix2netmask(shift);
 }
   
 sub iporsubtodec
@@ -379,7 +333,7 @@ sub iporsubtodec
        }
        #Subnet already in decimal and valid?
        if ($mask=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255  && $2<=$1 && $3<=$2  && $4<=$3 )))       {
-               for (my $i=8;$i<=32;$i++){
+               for (my $i=0;$i<=32;$i++){
                        if (&General::cidrtosub($i) eq $mask){
                                if ($full == 0){return $mask;}else{
                                                         return $net."/".$mask;
@@ -388,7 +342,7 @@ sub iporsubtodec
                }       
        }
        #Subnet in binary format?
-       if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=8))){
+       if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=0))){
                        if($full == 0){ return &General::cidrtosub($mask);}else{
                                                 return $net."/".&General::cidrtosub($mask);
                        }
@@ -415,7 +369,7 @@ sub iporsubtocidr
        }
        #Subnet in decimal and valid?
        if ($mask=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255  && $2<=$1 && $3<=$2  && $4<=$3 )))       {
-               for (my $i=8;$i<=32;$i++){
+               for (my $i=0;$i<=32;$i++){
                        if (&General::cidrtosub($i) eq $mask){
                                if ($full == 0){return &General::subtocidr($mask);}else{
                                                         return $net."/".&General::subtocidr($mask);
@@ -424,7 +378,7 @@ sub iporsubtocidr
                }       
        }
        #Subnet already in binary format?
-       if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=8))){
+       if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=0))){
                        if($full == 0){ return $mask;}else{
                                                 return $net."/".$mask;
                        }
@@ -434,15 +388,10 @@ sub iporsubtocidr
        return 3;
 }
 
-sub getnetworkip
-{
-       #Gets:  IP, CIDR    (10.10.10.0-255, 24)
-       #Gives:  10.10.10.0
-       my ($ccdip,$ccdsubnet) = @_;
-       my $ip_address_binary = inet_aton( $ccdip );
-       my $netmask_binary    = ~pack("N", (2**(32-$ccdsubnet))-1);
-       my $network_address    = inet_ntoa( $ip_address_binary & $netmask_binary );
-       return $network_address;
+sub getnetworkip {
+       my $arg = join("/", @_);
+
+       return &Network::get_netaddress($arg);
 }
 
 sub getccdbc
@@ -457,46 +406,20 @@ sub getccdbc
        return $broadcast_address;
 }
 
-sub ip2dec 
-{
-    my $ip_num;
-    my $ip=$_[0];
-    if ( $ip =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ ) {
-        $ip_num = (($1*256**3) + ($2*256**2) + ($3*256) + $4);
-    } else {
-        $ip_num = -1;
-    }
-    $ip_num = (($1*256**3) + ($2*256**2) + ($3*256) + $4);
-    return($ip_num);
+sub ip2dec  {
+       return &Network::ip2bin(shift);
 }
 
-sub dec2ip 
-{
-    my $ip;
-    my $ip_num=$_[0];
-       my $o1=$ip_num%256;
-       $ip_num=int($ip_num/256);
-       my $o2=$ip_num%256;
-       $ip_num=int($ip_num/256);
-       my $o3=$ip_num%256;
-       $ip_num=int($ip_num/256);
-       my $o4=$ip_num%256;
-       $ip="$o4.$o3.$o2.$o1";
-    return ($ip);
+sub dec2ip  {
+       return &Network::bin2ip(shift);
 }
 
-sub getnextip
-{
-       my $decip=&ip2dec($_[0]);
-       $decip=$decip+4;
-       return &dec2ip($decip);
+sub getnextip {
+       return &Network::find_next_ip_address(shift, 4);
 }
 
-sub getlastip
-{
-       my $decip=&ip2dec($_[0]);
-       $decip--;
-       return &dec2ip($decip);
+sub getlastip {
+       return &Network::find_next_ip_address(shift, -1);
 }
 
 sub validipandmask
@@ -514,13 +437,13 @@ sub validipandmask
        if ($ccdip=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1>0 && $1<=255 && $2>=0 && $2<=255 && $3>=0 && $3<=255 && $4<=255 ))) {
                #Subnet in decimal and valid?
                if ($ccdsubnet=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255  && $2<=$1 && $3<=$2  && $4<=$3 )))  {
-                       for (my $i=8;$i<=32;$i++){
+                       for (my $i=0;$i<=32;$i++){
                                if (&General::cidrtosub($i) eq $ccdsubnet){
                                        return 1;
                                }
-                       }       
+                       }
                #Subnet already in binary format?
-               }elsif ($ccdsubnet=~/^(\d{1,2})$/ && (($1<=32 && $1>=8))){
+               }elsif ($ccdsubnet=~/^(\d{1,2})$/ && (($1<=32 && $1>=0))){
                        return 1;
                }else{
                        return 0;
@@ -532,24 +455,46 @@ sub validipandmask
 
 sub checksubnets
 {
-       my %ccdconfhash=();                     
-       my @ccdconf=();                         
-       my $ccdname=$_[0];                      
-       my $ccdnet=$_[1];                       
+       my %ccdconfhash=();
+       my %ovpnconfhash=();
+       my %vpnconf=();
+       my %ipsecconf=();
+       my %ownnet=();
+       my %ovpnconf=();
+       my @ccdconf=();
+       my $ccdname=$_[0];
+       my $ccdnet=$_[1];
+       my $ownnet=$_[2];
        my $errormessage;
        my ($ip,$cidr)=split(/\//,$ccdnet);
        $cidr=&iporsubtocidr($cidr);
+
        #get OVPN-Subnet (dynamic range)
-       my %ovpnconf=();
        &readhash("${General::swroot}/ovpn/settings", \%ovpnconf);
        my ($ovpnip,$ovpncidr)= split (/\//,$ovpnconf{'DOVPN_SUBNET'});
        $ovpncidr=&iporsubtocidr($ovpncidr);
+
        #check if we try to use same network as ovpn server
        if ("$ip/$cidr" eq "$ovpnip/$ovpncidr") {
                        $errormessage=$errormessage.$Lang::tr{'ccd err isovpnnet'}."<br>";
                        return $errormessage;
        }
-       #check if we use a network-name/subnet that already exists
+
+       #check if we try to use same network as another ovpn N2N
+       if($ownnet ne 'ovpn'){
+               &readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ovpnconfhash);
+               foreach my $key (keys %ovpnconfhash) {
+                       if ($ovpnconfhash{$key}[3] eq 'net'){
+                               my @ovpnnet=split (/\//,$ovpnconfhash{$key}[11]);
+                               if (&IpInSubnet($ip,$ovpnnet[0],&iporsubtodec($ovpnnet[1]))){
+                                       $errormessage=$errormessage.$Lang::tr{'ccd err isovpnn2n'}." $ovpnconfhash{$key}[1] <br>";
+                                       return $errormessage;
+                               }
+                       }
+               }
+       }
+
+       #check if we use a network-name/subnet (static-ovpn) that already exists
        &readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
        foreach my $key (keys %ccdconfhash) {
                @ccdconf=split(/\//,$ccdconfhash{$key}[1]);
@@ -561,34 +506,60 @@ sub checksubnets
                my ($newip,$newsub) = split(/\//,$ccdnet);
                if (&IpInSubnet($newip,$ccdconf[0],&iporsubtodec($ccdconf[1]))) 
                {
-                       $errormessage=$errormessage.$Lang::tr{'ccd err issubnet'}."<br>";
+                       $errormessage=$errormessage.$Lang::tr{'ccd err issubnet'}." $ccdconfhash{$key}[0]<br>";
                        return $errormessage;
                }
        }
+
        #check if we use a ipsec right network which is already defined
-       my %ipsecconf=();
-       &General::readhasharray("${General::swroot}/vpn/config", \%ipsecconf);
-       foreach my $key (keys %ipsecconf){
-               if ($ipsecconf{$key}[11] ne ''){
-                       my ($ipsecip,$ipsecsub) = split (/\//, $ipsecconf{$key}[11]);
-                       $ipsecsub=&iporsubtodec($ipsecsub);
-                       if($ipsecconf{$key}[1] ne $ccdname){
-                               if ( &IpInSubnet ($ip,$ipsecip,$ipsecsub) ){
-                                       $errormessage=$Lang::tr{'ccd err isipsecnet'}." Name:  $ipsecconf{$key}[1]";
-                                       return $errormessage;
+       if($ownnet ne 'ipsec'){
+               &General::readhasharray("${General::swroot}/vpn/config", \%ipsecconf);
+               foreach my $key (keys %ipsecconf){
+                       if ($ipsecconf{$key}[11] ne ''){
+                               my ($ipsecip,$ipsecsub) = split (/\//, $ipsecconf{$key}[11]);
+                               $ipsecsub=&iporsubtodec($ipsecsub);
+                               if($ipsecconf{$key}[1] ne $ccdname){
+                                       if ( &IpInSubnet ($ip,$ipsecip,$ipsecsub) ){
+                                               $errormessage=$Lang::tr{'ccd err isipsecnet'}." Name:  $ipsecconf{$key}[1]";
+                                               return $errormessage;
+                                       }
                                }
                        }
                }
        }
+
+       #check if we use the ipsec RW Network (if defined)
+       &readhash("${General::swroot}/vpn/settings", \%vpnconf);
+       if ($vpnconf{'RW_NET'} ne ''){
+               my ($ipsecrwnet,$ipsecrwsub)=split (/\//, $vpnconf{'RW_NET'});
+               if (&IpInSubnet($ip,$ipsecrwnet,&iporsubtodec($ipsecrwsub)))
+               {
+                       $errormessage=$errormessage.$Lang::tr{'ccd err isipsecrw'}."<br>";
+                       return $errormessage;
+               }
+       }
+
        #check if we use one of ipfire's networks (green,orange,blue)
-       my %ownnet=();
        &readhash("${General::swroot}/ethernet/settings", \%ownnet);
-       if (($ownnet{'GREEN_NETADDRESS'}        ne '' && $ownnet{'GREEN_NETADDRESS'}    ne '0.0.0.0') && &IpInSubnet($ownnet{'GREEN_NETADDRESS'},$ip,&iporsubtodec($cidr))){ $errormessage=$Lang::tr{'ccd err green'};return $errormessage;}
-       if (($ownnet{'ORANGE_NETADDRESS'}       ne '' && $ownnet{'ORANGE_NETADDRESS'}   ne '0.0.0.0') && &IpInSubnet($ownnet{'ORANGE_NETADDRESS'},$ip,&iporsubtodec($cidr))){ $errormessage=$Lang::tr{'ccd err orange'};return $errormessage;}
-       if (($ownnet{'BLUE_NETADDRESS'}         ne '' && $ownnet{'BLUE_NETADDRESS'}     ne '0.0.0.0') && &IpInSubnet($ownnet{'BLUE_NETADDRESS'},$ip,&iporsubtodec($cidr))){ $errormessage=$Lang::tr{'ccd err blue'};return $errormessage;}
-       if (($ownnet{'RED_NETADDRESS'}          ne '' && $ownnet{'RED_NETADDRESS'}              ne '0.0.0.0') && &IpInSubnet($ownnet{'RED_NETADDRESS'},$ip,&iporsubtodec($cidr))){ $errormessage=$Lang::tr{'ccd err red'};return $errormessage;}
+       if (($ownnet{'GREEN_NETADDRESS'}        ne '' && $ownnet{'GREEN_NETADDRESS'}    ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'GREEN_NETADDRESS'},&iporsubtodec($ownnet{'GREEN_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err green'};return $errormessage;}
+       if (($ownnet{'ORANGE_NETADDRESS'}       ne '' && $ownnet{'ORANGE_NETADDRESS'}   ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'ORANGE_NETADDRESS'},&iporsubtodec($ownnet{'ORANGE_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err orange'};return $errormessage;}
+       if (($ownnet{'BLUE_NETADDRESS'}         ne '' && $ownnet{'BLUE_NETADDRESS'}     ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'BLUE_NETADDRESS'},&iporsubtodec($ownnet{'BLUE_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err blue'};return $errormessage;}
+       if (($ownnet{'RED_NETADDRESS'}          ne '' && $ownnet{'RED_NETADDRESS'}              ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'RED_NETADDRESS'},&iporsubtodec($ownnet{'RED_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err red'};return $errormessage;}
 }
 
+sub check_net_internal{
+       my $network=shift;
+       my ($ip,$cidr)=split(/\//,$network);
+       my %ownnet=();
+       my $errormessage;
+       $cidr=&iporsubtocidr($cidr);
+       #check if we use one of ipfire's networks (green,orange,blue)
+       &readhash("${General::swroot}/ethernet/settings", \%ownnet);
+       if (($ownnet{'GREEN_NETADDRESS'}        ne '' && $ownnet{'GREEN_NETADDRESS'}    ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'GREEN_NETADDRESS'},&iporsubtodec($ownnet{'GREEN_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err green'};return $errormessage;}
+       if (($ownnet{'ORANGE_NETADDRESS'}       ne '' && $ownnet{'ORANGE_NETADDRESS'}   ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'ORANGE_NETADDRESS'},&iporsubtodec($ownnet{'ORANGE_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err orange'};return $errormessage;}
+       if (($ownnet{'BLUE_NETADDRESS'}         ne '' && $ownnet{'BLUE_NETADDRESS'}     ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'BLUE_NETADDRESS'},&iporsubtodec($ownnet{'BLUE_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err blue'};return $errormessage;}
+       if (($ownnet{'RED_NETADDRESS'}          ne '' && $ownnet{'RED_NETADDRESS'}              ne '0.0.0.0') && &IpInSubnet($ip,$ownnet{'RED_NETADDRESS'},&iporsubtodec($ownnet{'RED_NETMASK'}))){ $errormessage=$Lang::tr{'ccd err red'};return $errormessage;}
+}
 
 sub validport
 {
@@ -659,9 +630,8 @@ sub validdomainname
        my @parts = split (/\./, $domainname);  # Split hostname at the '.'
 
        foreach $part (@parts) {
-               # Each part should be at least two characters in length
-               # but no more than 63 characters
-               if (length ($part) < 2 || length ($part) > 63) {
+               # Each part should be no more than 63 characters in length
+               if (length ($part) < 1 || length ($part) > 63) {
                        return 0;}
                # Only valid characters are a-z, A-Z, 0-9 and -
                if ($part !~ /^[a-zA-Z0-9-]*$/) {
@@ -744,19 +714,12 @@ sub validportrange # used to check a port range
        }
 }
 
-# Test if IP is within a subnet
-# Call: IpInSubnet (Addr, Subnet, Subnet Mask)
-#       Subnet can be an IP of the subnet: 10.0.0.0 or 10.0.0.1
-#       Everything in dottted notation
-# Return: TRUE/FALSE
-sub IpInSubnet
-{
-    my $ip = unpack('N', &Socket::inet_aton(shift));
-    my $start = unpack('N', &Socket::inet_aton(shift));
-    my $mask  = unpack('N', &Socket::inet_aton(shift));
-       $start &= $mask;  # base of subnet...
-    my $end   = $start + ~$mask;
-    return (($ip >= $start) && ($ip <= $end));
+sub IpInSubnet {
+       my $addr = shift;
+       my $network = shift;
+       my $netmask = shift;
+
+       return &Network::ip_address_in_network($addr, "$network/$netmask");
 }
 
 #
@@ -764,32 +727,25 @@ sub IpInSubnet
 # Call: NextIP ('1.1.1.1');
 # Return: '1.1.1.2'
 #
-sub NextIP
-{
-    return &Socket::inet_ntoa( pack("N", 1 +  unpack('N', &Socket::inet_aton(shift))
-                                  )
-                            );
+sub NextIP {
+       return &Network::find_next_ip_address(shift, 1);
 }
-sub NextIP2
-{
-    return &Socket::inet_ntoa( pack("N", 4 +  unpack('N', &Socket::inet_aton(shift))
-                                  )
-                            );
+
+sub NextIP2 {
+       return &Network::find_next_ip_address(shift, 4);
 }
-sub ipcidr
-{
+
+sub ipcidr {
        my ($ip,$cidr) = &Net::IPv4Addr::ipv4_parse(shift);
        return "$ip\/$cidr";
 }
 
-sub ipcidr2msk
-{
+sub ipcidr2msk {
        my ($ip,$cidr) = &Net::IPv4Addr::ipv4_parse(shift);
        my $netmask = &Net::IPv4Addr::ipv4_cidr2msk($cidr);
        return "$ip\/$netmask";
 }
 
-
 sub validemail {
     my $mail = shift;
     return 0 if ( $mail !~ /^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/ );
@@ -1065,7 +1021,7 @@ sub GetIcmpDescription ($) {
     'SKIP',
     'Photur',                          #40
     'Experimental');
-    if ($index>41) {return 'unknown'} else {return @icmp_description[$index]};
+    if ($index>41) {return 'unknown'} else {return $icmp_description[$index]};
 }
 
 sub GetCoreUpdateVersion() {
@@ -1137,4 +1093,61 @@ sub write_file_utf8 ($) {
        return; 
 }
 
+my $FIREWALL_RELOAD_INDICATOR = "${General::swroot}/firewall/reread";
+
+sub firewall_config_changed() {
+       open FILE, ">$FIREWALL_RELOAD_INDICATOR" or die "Could not open $FIREWALL_RELOAD_INDICATOR";
+       close FILE;
+}
+
+sub firewall_needs_reload() {
+       if (-e "$FIREWALL_RELOAD_INDICATOR") {
+               return 1;
+       }
+
+       return 0;
+}
+
+sub firewall_reload() {
+       system("/usr/local/bin/firewallctrl");
+}
+
+# Function which will return the used interface for the red network zone (red0, ppp0, etc).
+sub get_red_interface() {
+
+       open(IFACE, "${General::swroot}/red/iface") or die "Could not open /var/ipfire/red/iface";
+
+       my $interface = <IFACE>;
+       close(IFACE);
+       chomp $interface;
+
+       return $interface;
+}
+
+# Function to get the county name by a given country code.
+sub get_full_country_name($) {
+       my ($input) = @_;
+       my $name;
+
+       # Remove whitespaces.
+       chomp($input);
+
+       # Convert input into lower case format.
+       my $code = lc($input);
+
+       # Handle country codes which are not in the list.
+       if ($code eq "a1") { $name = "Anonymous Proxy" }
+       elsif ($code eq "a2") { $name = "Satellite Provider" }
+       elsif ($code eq "o1") { $name = "Other Country" }
+       elsif ($code eq "ap") { $name = "Asia/Pacific Region" }
+       elsif ($code eq "eu") { $name = "Europe" }
+       elsif ($code eq "yu") { $name = "Yugoslavia" }
+       else {
+               # Use perl built-in module to get the country code.
+               $name = &Locale::Country::code2country($code);
+       }
+
+       return $name;
+}
+
 1;