use strict;
use Socket;
use IO::Socket;
+use Locale::Codes::Country;
use Net::SSLeay;
use Net::IPv4Addr qw(:all);
$|=1; # line buffering
$General::noipprefix = 'noipg-';
$General::adminmanualurl = 'http://wiki.ipfire.org';
+require "${General::swroot}/network-functions.pl";
+
+# Function to remove duplicates from an array
+sub uniq { my %seen; grep !$seen{$_}++, @_ }
+
#
# log ("message") use default 'ipcop' tag
# log ("tag","message") use your tag
while (<FILE>)
{
chop;
+
+ # Skip comments.
+ next if ($_ =~ /^#/);
+
($var, $val) = split /=/, $_, 2;
if ($var)
{
sub age {
my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
$atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];
- my $totalsecs = time() - $mtime;
+ my $t = time() - $mtime;
+
+ return &format_time($t);
+}
+
+sub format_time($) {
+ my $totalsecs = shift;
my @s = ();
my $secs = $totalsecs % 60;
}
}
-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
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
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
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
my $ccdname=$_[0];
my $ccdnet=$_[1];
my $ownnet=$_[2];
+ my $checktype=$_[3];
my $errormessage;
my ($ip,$cidr)=split(/\//,$ccdnet);
$cidr=&iporsubtocidr($cidr);
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;
+ if ($ipsecconf{$key}[11] ne '' && $ipsecconf{$key}[36] eq ""){
+ foreach my $ipsecsubitem (split(/\|/, $ipsecconf{$key}[11])) {
+ 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;
+ }
}
}
}
return $errormessage;
}
}
+
+ #call check_net_internal
+ if ($checktype eq "exact")
+ {
+ &General::check_net_internal_exact($ccdnet);
+ }else{
+ &General::check_net_internal_range($ccdnet);
+ }
+}
+sub check_net_internal_range{
+ 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{'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{
+sub check_net_internal_exact{
my $network=shift;
my ($ip,$cidr)=split(/\//,$network);
my %ownnet=();
$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;}
+ if (($ownnet{'GREEN_NETADDRESS'} ne '' && $ownnet{'GREEN_NETADDRESS'} ne '0.0.0.0') && &Network::network_equal("$ownnet{'GREEN_NETADDRESS'}/$ownnet{'GREEN_NETMASK'}", $network)){ $errormessage=$Lang::tr{'ccd err green'};return $errormessage;}
+ if (($ownnet{'ORANGE_NETADDRESS'} ne '' && $ownnet{'ORANGE_NETADDRESS'} ne '0.0.0.0') && &Network::network_equal("$ownnet{'ORANGE_NETADDRESS'}/$ownnet{'ORANGE_NETMASK'}", $network)){ $errormessage=$Lang::tr{'ccd err orange'};return $errormessage;}
+ if (($ownnet{'BLUE_NETADDRESS'} ne '' && $ownnet{'BLUE_NETADDRESS'} ne '0.0.0.0') && &Network::network_equal("$ownnet{'BLUE_NETADDRESS'}/$ownnet{'BLUE_NETMASK'}", $network)){ $errormessage=$Lang::tr{'ccd err blue'};return $errormessage;}
+ if (($ownnet{'RED_NETADDRESS'} ne '' && $ownnet{'RED_NETADDRESS'} ne '0.0.0.0') && &Network::network_equal("$ownnet{'RED_NETADDRESS'}/$ownnet{'RED_NETMASK'}", $network)){ $errormessage=$Lang::tr{'ccd err red'};return $errormessage;}
}
sub validport
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) {
- return 0;}
- # Only valid characters are a-z, A-Z, 0-9 and -
- if ($part !~ /^[a-zA-Z0-9-]*$/) {
- return 0;}
- # First character can only be a letter or a digit
- if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
- return 0;}
- # Last character can only be a letter or a digit
- if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
+ # 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_-]*$/) {
+ return 0;
+ }
}
return 1;
}
my @parts = split (/\./, $fqdn); # Split hostname at the '.'
if (scalar(@parts) < 2) { # At least two parts should
return 0;} # exist in a FQDN
- # (i.e. hostname.domain)
+ # (i.e.hostname.domain)
foreach $part (@parts) {
# Each part should be at least one character in length
# but no more than 63 characters
}
}
-# 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");
}
#
# 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\.\-]+$/ );
- return 0 if ( $mail =~ /^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/);
- return 0 if ( $mail !~ /([0-9a-zA-Z]{1})\@./ );
- return 0 if ( $mail !~ /.\@([0-9a-zA-Z]{1})/ );
- return 0 if ( $mail =~ /.\.\-.|.\-\..|.\.\..|.\-\-./g );
- return 0 if ( $mail =~ /.\.\_.|.\-\_.|.\_\..|.\_\-.|.\_\_./g );
- return 0 if ( $mail !~ /\.([a-zA-Z]{2,4})$/ );
+ my $address = shift;
+ my @parts = split( /\@/, $address );
+ my $count=@parts;
+
+ #check if we have one part before and after '@'
+ return 0 if ( $count != 2 );
+
+ #check if one of the parts starts or ends with a dot
+ return 0 if ( substr($parts[0],0,1) eq '.' );
+ return 0 if ( substr($parts[0],-1,1) eq '.' );
+ return 0 if ( substr($parts[1],0,1) eq '.' );
+ return 0 if ( substr($parts[1],-1,1) eq '.' );
+
+ #check first addresspart (before '@' sign)
+ return 0 if ( $parts[0] !~ m/^[a-zA-Z0-9\.!\-\_\+#]+$/ );
+
+ #check second addresspart (after '@' sign)
+ return 0 if ( $parts[1] !~ m/^[a-zA-Z0-9\.\-]+$/ );
+
return 1;
}
return $interface;
}
+sub dnssec_status() {
+ my $path = "${General::swroot}/red/dnssec-status";
+
+ open(STATUS, $path) or return 0;
+ my $status = <STATUS>;
+ close(STATUS);
+
+ chomp($status);
+
+ return $status;
+}
+sub number_cpu_cores() {
+ open my $cpuinfo, "/proc/cpuinfo" or die "Can't open cpuinfo: $!\n";
+ my $cores = scalar (map /^processor/, <$cpuinfo>);
+ close $cpuinfo;
+
+ return $cores;
+}
+
+# Tiny function to grab a single IP-address from a given file.
+sub grab_address_from_file($) {
+ my ($file) = @_;
+
+ my $address;
+
+ # Check if the given file exists.
+ if(-f $file) {
+ # Open the file for reading.
+ open(FILE, $file) or die "Could not read from $file. $!\n";
+
+ # Read the address from the file.
+ $address = <FILE>;
+
+ # Close filehandle.
+ close(FILE);
+
+ # Remove newlines.
+ chomp($address);
+
+ # Check if the obtained address is valid.
+ if (&validip($address)) {
+ # Return the address.
+ return $address;
+ }
+ }
+
+ # Return nothing.
+ return;
+}
+
+# Function to get all configured and enabled nameservers.
+sub get_nameservers () {
+ my %settings;
+ my %servers;
+
+ my @nameservers;
+
+ # Read DNS configuration.
+ &readhash("$General::swroot/dns/settings", \%settings);
+
+ # Read configured DNS servers.
+ &readhasharray("$General::swroot/dns/servers", \%servers);
+
+ # Check if the ISP assigned server should be used.
+ if ($settings{'USE_ISP_NAMESERVERS'} eq "on") {
+ # Assign ISP nameserver files.
+ my @ISP_nameserver_files = ( "/var/run/dns1", "/var/run/dns2" );
+
+ # Loop through the array of ISP assigned DNS servers.
+ foreach my $file (@ISP_nameserver_files) {
+ # Grab the IP address.
+ my $address = &grab_address_from_file($file);
+
+ # Check if an address has been grabbed.
+ if ($address) {
+ # Add the address to the array of nameservers.
+ push(@nameservers, $address);
+ }
+ }
+ }
+
+ # Check if DNS servers are configured.
+ if (%servers) {
+ # Loop through the hash of configured DNS servers.
+ foreach my $id (keys %servers) {
+ my $address = $servers{$id}[0];
+ my $status = $servers{$id}[2];
+
+ # Check if the current processed server is enabled.
+ if ($status eq "enabled") {
+ # Add the address to the array of nameservers.
+ push(@nameservers, $address);
+ }
+ }
+ }
+
+ # Return the array.
+ return &uniq(@nameservers);
+}
+
+# Function to format a string containing the amount of bytes to
+# something human-readable.
+sub formatBytes {
+ # Private array which contains the units.
+ my @units = qw(B KB MB GB TB PB);
+
+ my $bytes = shift;
+ my $unit;
+
+ # Loop through the array of units.
+ foreach my $element (@units) {
+ # Assign current processed element to unit.
+ $unit = $element;
+
+ # Break loop if the bytes are less than the next unit.
+ last if $bytes < 1024;
+
+ # Divide bytes amount with 1024.
+ $bytes /= 1024;
+ }
+
+ # Return the divided and rounded bytes count and the unit.
+ return sprintf("%.2f %s", $bytes, $unit);
+}
+
+# Cloud Stuff
+
+sub running_in_cloud() {
+ return &running_on_ec2() || &running_on_gcp();
+}
+
+sub running_on_ec2() {
+ if (-e "/var/run/aws-instance-id") {
+ return 1;
+ }
+
+ return 0;
+}
+
+sub running_on_gcp() {
+ if (-e "/var/run/gcp-instance-id") {
+ return 1;
+ }
+
+ return 0;
+}
+
1;