]> git.ipfire.org Git - ipfire-2.x.git/blame - config/cfgroot/general-functions.pl
samba: remove SO_xxxBUF size definitions from default config
[ipfire-2.x.git] / config / cfgroot / general-functions.pl
CommitLineData
ac1cfefa
MT
1# SmoothWall CGIs
2#
3# This code is distributed under the terms of the GPL
4#
5# (c) The SmoothWall Team
6# Copyright (C) 2002 Alex Hudson - getcgihash() rewrite
7# Copyright (C) 2002 Bob Grant <bob@cache.ucr.edu> - validmac()
8# Copyright (c) 2002/04/13 Steve Bootes - add alias section, helper functions
9# Copyright (c) 2002/08/23 Mark Wormgoor <mark@wormgoor.com> validfqdn()
10# Copyright (c) 2003/09/11 Darren Critchley <darrenc@telus.net> srtarray()
11#
12# $Id: general-functions.pl,v 1.1.2.26 2006/01/04 16:33:55 franck78 Exp $
13#
14
15package General;
16
17use strict;
18use Socket;
19use IO::Socket;
c545beb1 20use Net::SSLeay;
8c877a82 21use Net::IPv4Addr qw(:all);
ac1cfefa
MT
22$|=1; # line buffering
23
776a1761
MT
24$General::version = 'VERSION';
25$General::swroot = 'CONFIG_ROOT';
ac1cfefa 26$General::noipprefix = 'noipg-';
c545beb1 27$General::adminmanualurl = 'http://wiki.ipfire.org';
ac1cfefa 28
4e9a2b57
MT
29require "${General::swroot}/network-functions.pl";
30
e8adbea9
AF
31# Function to remove duplicates from an array
32sub uniq { my %seen; grep !$seen{$_}++, @_ }
33
c545beb1
MT
34#
35# log ("message") use default 'ipcop' tag
36# log ("tag","message") use your tag
37#
ac1cfefa
MT
38sub log
39{
c545beb1
MT
40 my $tag='ipfire';
41 $tag = shift if (@_>1);
ac1cfefa
MT
42 my $logmessage = $_[0];
43 $logmessage =~ /([\w\W]*)/;
44 $logmessage = $1;
77007ce5 45 system('logger', '-t', $tag, $logmessage);
ac1cfefa 46}
111c99dd
MT
47sub setup_default_networks
48{
49 my %netsettings=();
50 my $defaultNetworks = shift;
51
52 &readhash("/var/ipfire/ethernet/settings", \%netsettings);
53
54 # Get current defined networks (Red, Green, Blue, Orange)
55 $defaultNetworks->{$Lang::tr{'fwhost any'}}{'IPT'} = "0.0.0.0/0.0.0.0";
56 $defaultNetworks->{$Lang::tr{'fwhost any'}}{'NAME'} = "ALL";
57
58 $defaultNetworks->{$Lang::tr{'green'}}{'IPT'} = "$netsettings{'GREEN_NETADDRESS'}/$netsettings{'GREEN_NETMASK'}";
68f6312a 59 $defaultNetworks->{$Lang::tr{'green'}}{'NET'} = "$netsettings{'GREEN_ADDRESS'}";
111c99dd
MT
60 $defaultNetworks->{$Lang::tr{'green'}}{'NAME'} = "GREEN";
61
b9648e58 62 if ($netsettings{'RED_DEV'} ne ''){
223d3b1d 63 $defaultNetworks->{$Lang::tr{'fwdfw red'}}{'IPT'} = "$netsettings{'RED_NETADDRESS'}/$netsettings{'RED_NETMASK'}";
68f6312a 64 $defaultNetworks->{$Lang::tr{'fwdfw red'}}{'NET'} = "$netsettings{'RED_ADDRESS'}";
223d3b1d 65 $defaultNetworks->{$Lang::tr{'fwdfw red'}}{'NAME'} = "RED";
b9648e58 66 }
111c99dd
MT
67 if ($netsettings{'ORANGE_DEV'} ne ''){
68 $defaultNetworks->{$Lang::tr{'orange'}}{'IPT'} = "$netsettings{'ORANGE_NETADDRESS'}/$netsettings{'ORANGE_NETMASK'}";
68f6312a 69 $defaultNetworks->{$Lang::tr{'orange'}}{'NET'} = "$netsettings{'ORANGE_ADDRESS'}";
111c99dd
MT
70 $defaultNetworks->{$Lang::tr{'orange'}}{'NAME'} = "ORANGE";
71 }
72
73 if ($netsettings{'BLUE_DEV'} ne ''){
74 $defaultNetworks->{$Lang::tr{'blue'}}{'IPT'} = "$netsettings{'BLUE_NETADDRESS'}/$netsettings{'BLUE_NETMASK'}";
68f6312a 75 $defaultNetworks->{$Lang::tr{'blue'}}{'NET'} = "$netsettings{'BLUE_ADDRESS'}";
111c99dd
MT
76 $defaultNetworks->{$Lang::tr{'blue'}}{'NAME'} = "BLUE";
77 }
c7043621
AM
78
79 #IPFire himself
80 $defaultNetworks->{'IPFire'}{'NAME'} = "IPFire";
111c99dd
MT
81
82 # OpenVPN
83 if(-e "${General::swroot}/ovpn/settings")
84 {
85 my %ovpnSettings = ();
86 &readhash("${General::swroot}/ovpn/settings", \%ovpnSettings);
87
88 # OpenVPN on Red?
89 if(defined($ovpnSettings{'DOVPN_SUBNET'}))
90 {
91 my ($ip,$sub) = split(/\//,$ovpnSettings{'DOVPN_SUBNET'});
92 $sub=&General::iporsubtocidr($sub);
93 my @tempovpnsubnet = split("\/", $ovpnSettings{'DOVPN_SUBNET'});
1a8fde0e
AM
94 $defaultNetworks->{'OpenVPN ' ."($ip/$sub)"}{'ADR'} = $tempovpnsubnet[0];
95 $defaultNetworks->{'OpenVPN ' ."($ip/$sub)"}{'NAME'} = "OpenVPN-Dyn";
111c99dd
MT
96 }
97 } # end OpenVPN
98 # IPsec RW NET
99 if(-e "${General::swroot}/vpn/settings")
100 {
101 my %ipsecsettings = ();
102 &readhash("${General::swroot}/vpn/settings", \%ipsecsettings);
103 if($ipsecsettings{'RW_NET'} ne '')
104 {
105 my ($ip,$sub) = split(/\//,$ipsecsettings{'RW_NET'});
106 $sub=&General::iporsubtocidr($sub);
107 my @tempipsecsubnet = split("\/", $ipsecsettings{'RW_NET'});
6ee90535
AM
108 $defaultNetworks->{'IPsec RW (' .$ip."/".$sub.")"}{'ADR'} = $tempipsecsubnet[0];
109 $defaultNetworks->{'IPsec RW (' .$ip."/".$sub.")"}{'NAME'} = "IPsec RW";
110 $defaultNetworks->{'IPsec RW (' .$ip."/".$sub.")"}{'NET'} = &getnextip($ip);
111c99dd
MT
111 }
112 }
111c99dd
MT
113}
114sub get_aliases
115{
116
117 my $defaultNetworks = shift;
118 open(FILE, "${General::swroot}/ethernet/aliases") or die 'Unable to open aliases file.';
119 my @current = <FILE>;
120 close(FILE);
121 my $ctr = 0;
122 foreach my $line (@current)
123 {
124 if ($line ne ''){
125 chomp($line);
126 my @temp = split(/\,/,$line);
127 if ($temp[2] eq '') {
128 $temp[2] = "Alias $ctr : $temp[0]";
129 }
130 $defaultNetworks->{$temp[2]}{'IPT'} = "$temp[0]";
68f6312a 131 $defaultNetworks->{$temp[2]}{'NET'} = "$temp[0]";
111c99dd
MT
132
133 $ctr++;
134 }
135 }
136}
ac1cfefa
MT
137
138sub readhash
139{
140 my $filename = $_[0];
141 my $hash = $_[1];
142 my ($var, $val);
143
144
145 # Some ipcop code expects that readhash 'complete' the hash if new entries
146 # are presents. Not clear it !!!
147 #%$hash = ();
148
149 open(FILE, $filename) or die "Unable to read file $filename";
150
151 while (<FILE>)
152 {
153 chop;
9f5247f6
SS
154
155 # Skip comments.
06f57f72 156 next if ($_ =~ /^#/);
9f5247f6 157
ac1cfefa
MT
158 ($var, $val) = split /=/, $_, 2;
159 if ($var)
160 {
161 $val =~ s/^\'//g;
162 $val =~ s/\'$//g;
163
164 # Untaint variables read from hash
77007ce5
MT
165 # trim space from begin and end
166 $var =~ s/^\s+//;
167 $var =~ s/\s+$//;
168 $var =~ /([A-Za-z0-9_-]*)/;
169 $var = $1;
170 $val =~ /([\w\W]*)/;
171 $val = $1;
ac1cfefa
MT
172 $hash->{$var} = $val;
173 }
174 }
175 close FILE;
176}
177
178
179sub writehash
180{
181 my $filename = $_[0];
182 my $hash = $_[1];
183 my ($var, $val);
184
185 # write cgi vars to the file.
186 open(FILE, ">${filename}") or die "Unable to write file $filename";
187 flock FILE, 2;
188 foreach $var (keys %$hash)
189 {
ad60e3ea 190 if ( $var eq "__CGI__"){next;}
ac1cfefa
MT
191 $val = $hash->{$var};
192 # Darren Critchley Jan 17, 2003 added the following because when submitting with a graphic, the x and y
193 # location of the mouse are submitted as well, this was being written to the settings file causing
194 # some serious grief! This skips the variable.x and variable.y
195 if (!($var =~ /(.x|.y)$/)) {
196 if ($val =~ / /) {
197 $val = "\'$val\'"; }
198 if (!($var =~ /^ACTION/)) {
199 print FILE "${var}=${val}\n"; }
200 }
201 }
202 close FILE;
203}
204
90c2e164
CS
205sub writehashpart
206{
207 # This function replaces the given hash in the original hash by keeping the old
208 # content and just replacing the new content
209
210 my $filename = $_[0];
211 my $newhash = $_[1];
212 my %oldhash;
213 my ($var, $val);
214
215 readhash("${filename}", \%oldhash);
216
217 foreach $var (keys %$newhash){
218 $oldhash{$var}=$newhash->{$var};
219 }
220
221 # write cgi vars to the file.
222 open(FILE, ">${filename}") or die "Unable to write file $filename";
223 flock FILE, 2;
224 foreach $var (keys %oldhash)
225 {
226 if ( $var eq "__CGI__"){next;}
227 $val = $oldhash{$var};
228 # Darren Critchley Jan 17, 2003 added the following because when submitting with a graphic, the x and y
229 # location of the mouse are submitted as well, this was being written to the settings file causing
230 # some serious grief! This skips the variable.x and variable.y
231 if (!($var =~ /(.x|.y)$/)) {
232 if ($val =~ / /) {
233 $val = "\'$val\'"; }
234 if (!($var =~ /^ACTION/)) {
235 print FILE "${var}=${val}\n"; }
236 }
237 }
238 close FILE;
239}
ac1cfefa 240
1dc44471 241sub age {
ac1cfefa 242 my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
1dc44471 243 $atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];
a0b271e4
MT
244 my $t = time() - $mtime;
245
246 return &format_time($t);
247}
248
249sub format_time($) {
250 my $totalsecs = shift;
1dc44471 251 my @s = ();
ac1cfefa 252
ac1cfefa 253 my $secs = $totalsecs % 60;
1dc44471
MT
254 $totalsecs /= 60;
255 if ($secs > 0) {
256 push(@s, "${secs}s");
3687a2e2
JIW
257 }
258
1dc44471
MT
259 my $min = $totalsecs % 60;
260 $totalsecs /= 60;
261 if ($min > 0) {
262 push(@s, "${min}m");
3687a2e2
JIW
263 }
264
1dc44471
MT
265 my $hrs = $totalsecs % 24;
266 $totalsecs /= 24;
267 if ($hrs > 0) {
268 push(@s, "${hrs}h");
3687a2e2
JIW
269 }
270
1dc44471
MT
271 my $days = int($totalsecs);
272 if ($days > 0) {
273 push(@s, "${days}d");
3687a2e2 274 }
3687a2e2 275
1dc44471 276 return join(" ", reverse(@s));
ac1cfefa
MT
277}
278
279sub validip
280{
281 my $ip = $_[0];
282
283 if (!($ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)) {
284 return 0; }
285 else
286 {
287 my @octets = ($1, $2, $3, $4);
288 foreach $_ (@octets)
289 {
290 if (/^0./) {
291 return 0; }
292 if ($_ < 0 || $_ > 255) {
293 return 0; }
294 }
295 return 1;
296 }
297}
298
4e9a2b57
MT
299sub validmask {
300 my $mask = shift;
ac1cfefa 301
c1420324 302 return &Network::check_netmask($mask) || &Network::check_prefix($mask);
ac1cfefa
MT
303}
304
305sub validipormask
306{
307 my $ipormask = $_[0];
308
309 # see if it is a IP only.
310 if (&validip($ipormask)) {
311 return 1; }
312 # split it into number and mask.
313 if (!($ipormask =~ /^(.*?)\/(.*?)$/)) {
314 return 0; }
315 my $ip = $1;
316 my $mask = $2;
317 # first part not a ip?
318 if (!(&validip($ip))) {
319 return 0; }
320 return &validmask($mask);
321}
322
4e9a2b57
MT
323sub subtocidr {
324 return &Network::convert_netmask2prefix(shift);
8c877a82 325}
ac1cfefa 326
4e9a2b57
MT
327sub cidrtosub {
328 return &Network::convert_prefix2netmask(shift);
8c877a82
AM
329}
330
331sub iporsubtodec
332{
333 #Gets: Ip address or subnetmask in decimal oder CIDR
334 #Gives: What it gets only in CIDR format
335 my $subnet=$_[0];
336 my $net;
337 my $mask;
338 my $full=0;
339 if ($subnet =~ /^(.*?)\/(.*?)$/) {
340 ($net,$mask) = split (/\//,$subnet);
341 $full=1;
342 return "$subnet";
343 }else{
344 $mask=$subnet;
345 }
346 #Subnet already in decimal and valid?
347 if ($mask=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255 && $2<=$1 && $3<=$2 && $4<=$3 ))) {
7490b22e 348 for (my $i=0;$i<=32;$i++){
8c877a82
AM
349 if (&General::cidrtosub($i) eq $mask){
350 if ($full == 0){return $mask;}else{
351 return $net."/".$mask;
352 }
353 }
354 }
355 }
356 #Subnet in binary format?
7490b22e 357 if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=0))){
8c877a82
AM
358 if($full == 0){ return &General::cidrtosub($mask);}else{
359 return $net."/".&General::cidrtosub($mask);
360 }
361 }else{
362 return 3;
363 }
364 return 3;
365}
366
367
368sub iporsubtocidr
369{
370 #gets: Ip Address or subnetmask in decimal oder CIDR
371 #Gives: What it gets only in CIDR format
372 my $subnet=$_[0];
373 my $net;
374 my $mask;
375 my $full=0;
376 if ($subnet =~ /^(.*?)\/(.*?)$/) {
377 ($net,$mask) = split (/\//,$subnet);
378 $full=1;
379 }else{
380 $mask=$subnet;
381 }
382 #Subnet in decimal and valid?
383 if ($mask=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255 && $2<=$1 && $3<=$2 && $4<=$3 ))) {
7490b22e 384 for (my $i=0;$i<=32;$i++){
8c877a82
AM
385 if (&General::cidrtosub($i) eq $mask){
386 if ($full == 0){return &General::subtocidr($mask);}else{
387 return $net."/".&General::subtocidr($mask);
388 }
389 }
390 }
391 }
392 #Subnet already in binary format?
7490b22e 393 if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=0))){
8c877a82
AM
394 if($full == 0){ return $mask;}else{
395 return $net."/".$mask;
396 }
397 }else{
398 return 3;
399 }
400 return 3;
401}
402
4e9a2b57 403sub getnetworkip {
da05e076 404 my $arg = join("/", @_);
6a2a62cf
MT
405
406 return &Network::get_netaddress($arg);
8c877a82
AM
407}
408
409sub getccdbc
410{
411 #Gets: IP in Form ("192.168.0.0/24")
412 #Gives: Broadcastaddress of network
413 my $ccdnet=$_;
414 my ($ccdip,$ccdsubnet) = split "/",$ccdnet;
415 my $ip_address_binary = inet_aton( $ccdip );
416 my $netmask_binary = ~pack("N", (2**(32-$ccdsubnet))-1);
417 my $broadcast_address = inet_ntoa( $ip_address_binary | ~$netmask_binary );
418 return $broadcast_address;
419}
e81be1e1 420
4e9a2b57
MT
421sub ip2dec {
422 return &Network::ip2bin(shift);
8c877a82 423}
e81be1e1 424
4e9a2b57
MT
425sub dec2ip {
426 return &Network::bin2ip(shift);
427}
428
429sub getnextip {
430 return &Network::find_next_ip_address(shift, 4);
431}
432
433sub getlastip {
434 return &Network::find_next_ip_address(shift, -1);
8c877a82
AM
435}
436
437sub validipandmask
438{
439 #Gets: Ip address in 192.168.0.0/24 or 192.168.0.0/255.255.255.0 and checks if subnet valid
440 #Gives: True bzw 0 if success or false
441 my $ccdnet=$_[0];
442 my $subcidr;
443
444 if (!($ccdnet =~ /^(.*?)\/(.*?)$/)) {
445 return 0;
446 }
447 my ($ccdip,$ccdsubnet)=split (/\//, $ccdnet);
448 #IP valid?
449 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 ))) {
450 #Subnet in decimal and valid?
451 if ($ccdsubnet=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255 && $2<=$1 && $3<=$2 && $4<=$3 ))) {
7490b22e 452 for (my $i=0;$i<=32;$i++){
8c877a82
AM
453 if (&General::cidrtosub($i) eq $ccdsubnet){
454 return 1;
455 }
7490b22e 456 }
8c877a82 457 #Subnet already in binary format?
7490b22e 458 }elsif ($ccdsubnet=~/^(\d{1,2})$/ && (($1<=32 && $1>=0))){
8c877a82
AM
459 return 1;
460 }else{
461 return 0;
462 }
463
464 }
465 return 0;
ac1cfefa
MT
466}
467
e2429e8d
AM
468sub checksubnets
469{
4d81e0f3
AM
470 my %ccdconfhash=();
471 my %ovpnconfhash=();
472 my %vpnconf=();
473 my %ipsecconf=();
474 my %ownnet=();
475 my %ovpnconf=();
476 my @ccdconf=();
477 my $ccdname=$_[0];
478 my $ccdnet=$_[1];
479 my $ownnet=$_[2];
b7ab17ad 480 my $checktype=$_[3];
e2429e8d
AM
481 my $errormessage;
482 my ($ip,$cidr)=split(/\//,$ccdnet);
483 $cidr=&iporsubtocidr($cidr);
4d81e0f3 484
e2429e8d 485 #get OVPN-Subnet (dynamic range)
e2429e8d
AM
486 &readhash("${General::swroot}/ovpn/settings", \%ovpnconf);
487 my ($ovpnip,$ovpncidr)= split (/\//,$ovpnconf{'DOVPN_SUBNET'});
488 $ovpncidr=&iporsubtocidr($ovpncidr);
4d81e0f3 489
e2429e8d
AM
490 #check if we try to use same network as ovpn server
491 if ("$ip/$cidr" eq "$ovpnip/$ovpncidr") {
492 $errormessage=$errormessage.$Lang::tr{'ccd err isovpnnet'}."<br>";
493 return $errormessage;
494 }
4d81e0f3
AM
495
496 #check if we try to use same network as another ovpn N2N
497 if($ownnet ne 'ovpn'){
498 &readhasharray("${General::swroot}/ovpn/ovpnconfig", \%ovpnconfhash);
499 foreach my $key (keys %ovpnconfhash) {
500 if ($ovpnconfhash{$key}[3] eq 'net'){
501 my @ovpnnet=split (/\//,$ovpnconfhash{$key}[11]);
502 if (&IpInSubnet($ip,$ovpnnet[0],&iporsubtodec($ovpnnet[1]))){
503 $errormessage=$errormessage.$Lang::tr{'ccd err isovpnn2n'}." $ovpnconfhash{$key}[1] <br>";
504 return $errormessage;
505 }
506 }
507 }
508 }
509
510 #check if we use a network-name/subnet (static-ovpn) that already exists
e2429e8d
AM
511 &readhasharray("${General::swroot}/ovpn/ccd.conf", \%ccdconfhash);
512 foreach my $key (keys %ccdconfhash) {
513 @ccdconf=split(/\//,$ccdconfhash{$key}[1]);
514 if ($ccdname eq $ccdconfhash{$key}[0])
515 {
516 $errormessage=$errormessage.$Lang::tr{'ccd err nameexist'}."<br>";
517 return $errormessage;
518 }
519 my ($newip,$newsub) = split(/\//,$ccdnet);
520 if (&IpInSubnet($newip,$ccdconf[0],&iporsubtodec($ccdconf[1])))
521 {
4d81e0f3 522 $errormessage=$errormessage.$Lang::tr{'ccd err issubnet'}." $ccdconfhash{$key}[0]<br>";
e2429e8d
AM
523 return $errormessage;
524 }
e2429e8d 525 }
4d81e0f3 526
e2429e8d 527 #check if we use a ipsec right network which is already defined
4d81e0f3
AM
528 if($ownnet ne 'ipsec'){
529 &General::readhasharray("${General::swroot}/vpn/config", \%ipsecconf);
530 foreach my $key (keys %ipsecconf){
087e3023 531 if ($ipsecconf{$key}[11] ne '' && $ipsecconf{$key}[36] eq ""){
ecc9c73b
HG
532 foreach my $ipsecsubitem (split(/\|/, $ipsecconf{$key}[11])) {
533 my ($ipsecip,$ipsecsub) = split (/\//, $ipsecconf{$key}[11]);
534 $ipsecsub=&iporsubtodec($ipsecsub);
535 if($ipsecconf{$key}[1] ne $ccdname){
536 if ( &IpInSubnet ($ip,$ipsecip,$ipsecsub) ){
537 $errormessage=$Lang::tr{'ccd err isipsecnet'}." Name: $ipsecconf{$key}[1]";
538 return $errormessage;
539 }
4d81e0f3 540 }
f7e3d208 541 }
e2429e8d
AM
542 }
543 }
544 }
4d81e0f3
AM
545
546 #check if we use the ipsec RW Network (if defined)
547 &readhash("${General::swroot}/vpn/settings", \%vpnconf);
548 if ($vpnconf{'RW_NET'} ne ''){
549 my ($ipsecrwnet,$ipsecrwsub)=split (/\//, $vpnconf{'RW_NET'});
550 if (&IpInSubnet($ip,$ipsecrwnet,&iporsubtodec($ipsecrwsub)))
551 {
552 $errormessage=$errormessage.$Lang::tr{'ccd err isipsecrw'}."<br>";
553 return $errormessage;
554 }
555 }
4f857eea
AM
556
557 #call check_net_internal
b7ab17ad
AM
558 if ($checktype eq "exact")
559 {
560 &General::check_net_internal_exact($ccdnet);
561 }else{
562 &General::check_net_internal_range($ccdnet);
563 }
e2429e8d
AM
564}
565
b7ab17ad 566sub check_net_internal_range{
29f238b2
AM
567 my $network=shift;
568 my ($ip,$cidr)=split(/\//,$network);
569 my %ownnet=();
570 my $errormessage;
571 $cidr=&iporsubtocidr($cidr);
572 #check if we use one of ipfire's networks (green,orange,blue)
573 &readhash("${General::swroot}/ethernet/settings", \%ownnet);
65c3b7c9
MT
574 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;}
575 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;}
576 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;}
577 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;}
b7ab17ad
AM
578}
579
580sub check_net_internal_exact{
581 my $network=shift;
582 my ($ip,$cidr)=split(/\//,$network);
583 my %ownnet=();
584 my $errormessage;
585 $cidr=&iporsubtocidr($cidr);
586 #check if we use one of ipfire's networks (green,orange,blue)
587 &readhash("${General::swroot}/ethernet/settings", \%ownnet);
588 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;}
589 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;}
590 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;}
591 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;}
29f238b2 592}
e2429e8d 593
ac1cfefa
MT
594sub validport
595{
596 $_ = $_[0];
597
598 if (!/^\d+$/) {
599 return 0; }
600 if (/^0./) {
601 return 0; }
602 if ($_ >= 1 && $_ <= 65535) {
603 return 1; }
604 return 0;
605}
606
d30ea451
CS
607sub validproxyport
608{
609 $_ = $_[0];
610
611 if (!/^\d+$/) {
612 return 0; }
613 if (/^0./) {
614 return 0; }
615 if ($_ == 53 || $_ == 222 || $_ == 444 || $_ == 81 ) {
616 return 0; }
617 elsif ($_ >= 1 && $_ <= 65535) {
618 return 1; }
619 return 0;
620}
621
ac1cfefa
MT
622sub validmac
623{
624 my $checkmac = $_[0];
625 my $ot = '[0-9a-f]{2}'; # 2 Hex digits (one octet)
626 if ($checkmac !~ /^$ot:$ot:$ot:$ot:$ot:$ot$/i)
627 {
628 return 0;
629 }
630 return 1;
631}
632
633sub validhostname
634{
635 # Checks a hostname against RFC1035
636 my $hostname = $_[0];
637
638 # Each part should be at least two characters in length
639 # but no more than 63 characters
640 if (length ($hostname) < 1 || length ($hostname) > 63) {
641 return 0;}
642 # Only valid characters are a-z, A-Z, 0-9 and -
8c877a82 643 if ($hostname !~ /^[a-zA-Z0-9-\s]*$/) {
ac1cfefa
MT
644 return 0;}
645 # First character can only be a letter or a digit
646 if (substr ($hostname, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
647 return 0;}
648 # Last character can only be a letter or a digit
649 if (substr ($hostname, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
650 return 0;}
651 return 1;
652}
653
654sub validdomainname
655{
656 my $part;
657
658 # Checks a domain name against RFC1035
659 my $domainname = $_[0];
660 my @parts = split (/\./, $domainname); # Split hostname at the '.'
661
662 foreach $part (@parts) {
8ed77b03
AG
663 # Each part should be no more than 63 characters in length
664 if (length ($part) < 1 || length ($part) > 63) {
ac1cfefa 665 return 0;}
03306ff6
MT
666 # Only valid characters are a-z, A-Z, 0-9, _ and -
667 if ($part !~ /^[a-zA-Z0-9_-]*$/) {
668 return 0;
669 }
ac1cfefa
MT
670 }
671 return 1;
672}
673
674sub validfqdn
675{
676 my $part;
677
678 # Checks a fully qualified domain name against RFC1035
679 my $fqdn = $_[0];
680 my @parts = split (/\./, $fqdn); # Split hostname at the '.'
681 if (scalar(@parts) < 2) { # At least two parts should
682 return 0;} # exist in a FQDN
b00797e2 683 # (i.e.hostname.domain)
ac1cfefa
MT
684 foreach $part (@parts) {
685 # Each part should be at least one character in length
686 # but no more than 63 characters
687 if (length ($part) < 1 || length ($part) > 63) {
688 return 0;}
689 # Only valid characters are a-z, A-Z, 0-9 and -
690 if ($part !~ /^[a-zA-Z0-9-]*$/) {
691 return 0;}
692 # First character can only be a letter or a digit
693 if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
694 return 0;}
695 # Last character can only be a letter or a digit
696 if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
697 return 0;}
698 }
699 return 1;
700}
701
702sub validportrange # used to check a port range
703{
704 my $port = $_[0]; # port values
705 $port =~ tr/-/:/; # replace all - with colons just in case someone used -
706 my $srcdst = $_[1]; # is it a source or destination port
707
708 if (!($port =~ /^(\d+)\:(\d+)$/)) {
709
710 if (!(&validport($port))) {
711 if ($srcdst eq 'src'){
712 return $Lang::tr{'source port numbers'};
713 } else {
714 return $Lang::tr{'destination port numbers'};
715 }
716 }
717 }
718 else
719 {
720 my @ports = ($1, $2);
721 if ($1 >= $2){
722 if ($srcdst eq 'src'){
723 return $Lang::tr{'bad source range'};
724 } else {
725 return $Lang::tr{'bad destination range'};
726 }
727 }
728 foreach $_ (@ports)
729 {
730 if (!(&validport($_))) {
731 if ($srcdst eq 'src'){
732 return $Lang::tr{'source port numbers'};
733 } else {
734 return $Lang::tr{'destination port numbers'};
735 }
736 }
737 }
738 return;
739 }
740}
741
4e9a2b57 742sub IpInSubnet {
ab92dc0c
AM
743 my $addr = shift;
744 my $network = shift;
745 my $netmask = shift;
746
4e9a2b57 747 return &Network::ip_address_in_network($addr, "$network/$netmask");
ac1cfefa
MT
748}
749
c545beb1
MT
750#
751# Return the following IP (IP+1) in dotted notation.
752# Call: NextIP ('1.1.1.1');
753# Return: '1.1.1.2'
754#
4e9a2b57
MT
755sub NextIP {
756 return &Network::find_next_ip_address(shift, 1);
c545beb1 757}
4e9a2b57
MT
758
759sub NextIP2 {
760 return &Network::find_next_ip_address(shift, 4);
8c877a82 761}
4e9a2b57
MT
762
763sub ipcidr {
45762fc6
AF
764 my ($ip,$cidr) = &Net::IPv4Addr::ipv4_parse(shift);
765 return "$ip\/$cidr";
766}
767
4e9a2b57 768sub ipcidr2msk {
54fd0535
MT
769 my ($ip,$cidr) = &Net::IPv4Addr::ipv4_parse(shift);
770 my $netmask = &Net::IPv4Addr::ipv4_cidr2msk($cidr);
771 return "$ip\/$netmask";
772}
773
ac1cfefa 774sub validemail {
b00797e2
AM
775 my $address = shift;
776 my @parts = split( /\@/, $address );
777 my $count=@parts;
778
779 #check if we have one part before and after '@'
780 return 0 if ( $count != 2 );
781
782 #check if one of the parts starts or ends with a dot
783 return 0 if ( substr($parts[0],0,1) eq '.' );
784 return 0 if ( substr($parts[0],-1,1) eq '.' );
785 return 0 if ( substr($parts[1],0,1) eq '.' );
786 return 0 if ( substr($parts[1],-1,1) eq '.' );
787
788 #check first addresspart (before '@' sign)
cc724c14 789 return 0 if ( $parts[0] !~ m/^[a-zA-Z0-9\.!\-\_\+#]+$/ );
b00797e2
AM
790
791 #check second addresspart (after '@' sign)
792 return 0 if ( $parts[1] !~ m/^[a-zA-Z0-9\.\-]+$/ );
793
ac1cfefa
MT
794 return 1;
795}
796
c545beb1
MT
797#
798# Currently only vpnmain use this three procs (readhasharray, writehasharray, findhasharray)
799# The 'key' used is numeric but is perfectly unneeded! This will to be removed so don't use
800# this code. Vpnmain will be splitted in parts: x509/pki, connection ipsec, connection other,... .
801#
ac1cfefa
MT
802sub readhasharray {
803 my ($filename, $hash) = @_;
804 %$hash = ();
805
806 open(FILE, $filename) or die "Unable to read file $filename";
807
808 while (<FILE>) {
809 my ($key, $rest, @temp);
810 chomp;
811 ($key, $rest) = split (/,/, $_, 2);
c545beb1 812 if ($key =~ /^[0-9]+$/) {
ac1cfefa
MT
813 @temp = split (/,/, $rest);
814 $hash->{$key} = \@temp;
815 }
816 }
817 close FILE;
818 return;
819}
820
821sub writehasharray {
822 my ($filename, $hash) = @_;
823 my ($key, @temp, $i);
824
825 open(FILE, ">$filename") or die "Unable to write to file $filename";
826
827 foreach $key (keys %$hash) {
8c877a82
AM
828 if ($key =~ /^[0-9]+$/) {
829 print FILE "$key";
830 foreach $i (0 .. $#{$hash->{$key}}) {
831 print FILE ",$hash->{$key}[$i]";
832 }
833 print FILE "\n";
834 }
ac1cfefa
MT
835 }
836 close FILE;
837 return;
838}
839
840sub findhasharraykey {
841 foreach my $i (1 .. 1000000) {
842 if ( ! exists $_[0]{$i}) {
843 return $i;
844 }
845 }
846}
847
848sub srtarray
849# Darren Critchley - darrenc@telus.net - (c) 2003
850# &srtarray(SortOrder, AlphaNumeric, SortDirection, ArrayToBeSorted)
851# This subroutine will take the following parameters:
852# ColumnNumber = the column which you want to sort on, starts at 1
853# AlphaNumberic = a or n (lowercase) defines whether the sort should be alpha or numberic
854# SortDirection = asc or dsc (lowercase) Ascending or Descending sort
855# ArrayToBeSorted = the array that wants sorting
856#
857# Returns an array that is sorted to your specs
858#
859# If SortOrder is greater than the elements in array, then it defaults to the first element
860#
861{
862 my ($colno, $alpnum, $srtdir, @tobesorted) = @_;
863 my @tmparray;
864 my @srtedarray;
865 my $line;
866 my $newline;
867 my $ctr;
868 my $ttlitems = scalar @tobesorted; # want to know the number of rows in the passed array
869 if ($ttlitems < 1){ # if no items, don't waste our time lets leave
870 return (@tobesorted);
871 }
872 my @tmp = split(/\,/,$tobesorted[0]);
873 $ttlitems = scalar @tmp; # this should be the number of elements in each row of the passed in array
874
875 # Darren Critchley - validate parameters
876 if ($colno > $ttlitems){$colno = '1';}
877 $colno--; # remove one from colno to deal with arrays starting at 0
878 if($colno < 0){$colno = '0';}
879 if ($alpnum ne '') { $alpnum = lc($alpnum); } else { $alpnum = 'a'; }
880 if ($srtdir ne '') { $srtdir = lc($srtdir); } else { $srtdir = 'src'; }
881
882 foreach $line (@tobesorted)
883 {
884 chomp($line);
885 if ($line ne '') {
886 my @temp = split(/\,/,$line);
887 # Darren Critchley - juggle the fields so that the one we want to sort on is first
888 my $tmpholder = $temp[0];
889 $temp[0] = $temp[$colno];
890 $temp[$colno] = $tmpholder;
891 $newline = "";
892 for ($ctr=0; $ctr < $ttlitems ; $ctr++) {
893 $newline=$newline . $temp[$ctr] . ",";
894 }
895 chop($newline);
896 push(@tmparray,$newline);
897 }
898 }
899 if ($alpnum eq 'n') {
900 @tmparray = sort {$a <=> $b} @tmparray;
901 } else {
902 @tmparray = (sort @tmparray);
903 }
904 foreach $line (@tmparray)
905 {
906 chomp($line);
907 if ($line ne '') {
908 my @temp = split(/\,/,$line);
909 my $tmpholder = $temp[0];
910 $temp[0] = $temp[$colno];
911 $temp[$colno] = $tmpholder;
912 $newline = "";
913 for ($ctr=0; $ctr < $ttlitems ; $ctr++){
914 $newline=$newline . $temp[$ctr] . ",";
915 }
916 chop($newline);
917 push(@srtedarray,$newline);
918 }
919 }
920
921 if ($srtdir eq 'dsc') {
922 @tmparray = reverse(@srtedarray);
923 return (@tmparray);
924 } else {
925 return (@srtedarray);
926 }
927}
928
929sub FetchPublicIp {
930 my %proxysettings;
931 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
932 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
933 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
934 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
935 }
b2f8244a 936 my $user_agent = &MakeUserAgent();
0aa0cdcd 937 my ($out, $response) = Net::SSLeay::get_http( 'checkip4.dns.lightningwirelabs.com',
ac1cfefa
MT
938 80,
939 "/",
b2f8244a 940 Net::SSLeay::make_headers('User-Agent' => $user_agent )
ac1cfefa
MT
941 );
942 if ($response =~ m%HTTP/1\.. 200 OK%) {
5a2935b1 943 $out =~ /Your IP address is: (\d+.\d+.\d+.\d+)/;
ac1cfefa
MT
944 return $1;
945 }
946 return '';
947}
948
949#
950# Check if hostname.domain provided have IP provided
951# use gethostbyname to verify that
952# Params:
953# IP
954# hostname
955# domain
956# Output
957# 1 IP matches host.domain
958# 0 not in sync
959#
960sub DyndnsServiceSync ($;$;$) {
961
962 my ($ip,$hostName,$domain) = @_;
963 my @addresses;
964
965 #fix me no ip GROUP, what is the name ?
966 $hostName =~ s/$General::noipprefix//;
967 if ($hostName) { #may be empty
968 $hostName = "$hostName.$domain";
969 @addresses = gethostbyname($hostName);
970 }
971
972 if ($addresses[0] eq '') { # nothing returned ?
973 $hostName = $domain; # try resolving with domain only
974 @addresses = gethostbyname($hostName);
975 }
976
977 if ($addresses[0] ne '') { # got something ?
978 #&General::log("name:$addresses[0], alias:$addresses[1]");
979 # Build clear text list of IP
980 @addresses = map ( &Socket::inet_ntoa($_), @addresses[4..$#addresses]);
981 if (grep (/$ip/, @addresses)) {
982 return 1;
983 }
984 }
985 return 0;
986}
987#
988# This sub returns the red IP used to compare in DyndnsServiceSync
989#
990sub GetDyndnsRedIP {
991 my %settings;
992 &General::readhash("${General::swroot}/ddns/settings", \%settings);
993
994 open(IP, "${General::swroot}/red/local-ipaddress") or return 'unavailable';
995 my $ip = <IP>;
996 close(IP);
997 chomp $ip;
998
057dbeeb 999 # 100.64.0.0/10 is reserved for dual-stack lite (http://tools.ietf.org/html/rfc6598).
ac1cfefa
MT
1000 if (&General::IpInSubnet ($ip,'10.0.0.0','255.0.0.0') ||
1001 &General::IpInSubnet ($ip,'172.16.0.0.','255.240.0.0') ||
057dbeeb
MT
1002 &General::IpInSubnet ($ip,'192.168.0.0','255.255.0.0') ||
1003 &General::IpInSubnet ($ip,'100.64.0.0', '255.192.0.0'))
ac1cfefa
MT
1004 {
1005 if ($settings{'BEHINDROUTER'} eq 'FETCH_IP') {
1006 my $RealIP = &General::FetchPublicIp;
1007 $ip = (&General::validip ($RealIP) ? $RealIP : 'unavailable');
1008 }
1009 }
1010 return $ip;
1011}
c545beb1
MT
1012
1013# Translate ICMP code to text
1014# ref: http://www.iana.org/assignments/icmp-parameters
1015sub GetIcmpDescription ($) {
1016 my $index = shift;
1017 my @icmp_description = (
1018 'Echo Reply', #0
1019 'Unassigned',
1020 'Unassigned',
1021 'Destination Unreachable',
1022 'Source Quench',
1023 'Redirect',
1024 'Alternate Host Address',
1025 'Unassigned',
1026 'Echo',
1027 'Router Advertisement',
1028 'Router Solicitation', #10
1029 'Time Exceeded',
1030 'Parameter Problem',
1031 'Timestamp',
1032 'Timestamp Reply',
1033 'Information Request',
1034 'Information Reply',
1035 'Address Mask Request',
1036 'Address Mask Reply',
1037 'Reserved (for Security)',
1038 'Reserved (for Robustness Experiment)', #20
1039 'Reserved',
1040 'Reserved',
1041 'Reserved',
1042 'Reserved',
1043 'Reserved',
1044 'Reserved',
1045 'Reserved',
1046 'Reserved',
1047 'Reserved',
1048 'Traceroute', #30
1049 'Datagram Conversion Error',
1050 'Mobile Host Redirect',
1051 'IPv6 Where-Are-You',
1052 'IPv6 I-Am-Here',
1053 'Mobile Registration Request',
1054 'Mobile Registration Reply',
1055 'Domain Name Request',
1056 'Domain Name Reply',
1057 'SKIP',
1058 'Photur', #40
1059 'Experimental');
a2b3eba9 1060 if ($index>41) {return 'unknown'} else {return $icmp_description[$index]};
c545beb1 1061}
b2f8244a
MT
1062
1063sub GetCoreUpdateVersion() {
1064 my $core_update;
1065
1066 open(FILE, "/opt/pakfire/db/core/mine");
1067 while (<FILE>) {
1068 $core_update = $_;
1069 last;
1070 }
1071 close(FILE);
1072
1073 return $core_update;
1074}
1075
1076sub MakeUserAgent() {
1077 my $user_agent = "IPFire/$General::version";
1078
1079 my $core_update = &GetCoreUpdateVersion();
1080 if ($core_update ne "") {
1081 $user_agent .= "/$core_update";
1082 }
1083
1084 return $user_agent;
1085}
1086
61027579
MT
1087sub RedIsWireless() {
1088 # This function checks if a network device is a wireless device.
1089
1090 my %settings = ();
1091 &readhash("${General::swroot}/ethernet/settings", \%settings);
1092
1093 # Find the name of the network device.
1094 my $device = $settings{'RED_DEV'};
1095
1096 # Exit, if no device is configured.
1097 return 0 if ($device eq "");
1098
1099 # Return 1 if the device is a wireless one.
1100 my $path = "/sys/class/net/$device/wireless";
1101 if (-d $path) {
1102 return 1;
1103 }
1104
1105 # Otherwise return zero.
1106 return 0;
1107}
1108
dfee7582
SS
1109# Function to read a file with UTF-8 charset.
1110sub read_file_utf8 ($) {
1111 my ($file) = @_;
1112
1113 open my $in, '<:encoding(UTF-8)', $file or die "Could not open '$file' for reading $!";
1114 local $/ = undef;
1115 my $all = <$in>;
1116 close $in;
1117
3e862ce4 1118 return $all;
dfee7582
SS
1119}
1120
1121# Function to write a file with UTF-8 charset.
1122sub write_file_utf8 ($) {
1123 my ($file, $content) = @_;
1124
1125 open my $out, '>:encoding(UTF-8)', $file or die "Could not open '$file' for writing $!";;
1126 print $out $content;
1127 close $out;
1128
1129 return;
1130}
1131
6d8eb5de 1132my $FIREWALL_RELOAD_INDICATOR = "${General::swroot}/firewall/reread";
0e430797
MT
1133
1134sub firewall_config_changed() {
1135 open FILE, ">$FIREWALL_RELOAD_INDICATOR" or die "Could not open $FIREWALL_RELOAD_INDICATOR";
1136 close FILE;
1137}
1138
1139sub firewall_needs_reload() {
1140 if (-e "$FIREWALL_RELOAD_INDICATOR") {
1141 return 1;
1142 }
1143
1144 return 0;
1145}
1146
1147sub firewall_reload() {
8039a710 1148 system("/usr/local/bin/firewallctrl");
0e430797
MT
1149}
1150
4cb523d4
SS
1151# Function which will return the used interface for the red network zone (red0, ppp0, etc).
1152sub get_red_interface() {
1153
1154 open(IFACE, "${General::swroot}/red/iface") or die "Could not open /var/ipfire/red/iface";
1155
1156 my $interface = <IFACE>;
1157 close(IFACE);
1158 chomp $interface;
1159
1160 return $interface;
1161}
1162
183b23b5
MT
1163sub dnssec_status() {
1164 my $path = "${General::swroot}/red/dnssec-status";
1165
1166 open(STATUS, $path) or return 0;
1167 my $status = <STATUS>;
1168 close(STATUS);
1169
1170 chomp($status);
1171
1172 return $status;
1173}
1a3323f2
DW
1174sub number_cpu_cores() {
1175 open my $cpuinfo, "/proc/cpuinfo" or die "Can't open cpuinfo: $!\n";
1176 my $cores = scalar (map /^processor/, <$cpuinfo>);
1177 close $cpuinfo;
1178
1179 return $cores;
1180}
183b23b5 1181
97022524
SS
1182# Tiny function to grab a single IP-address from a given file.
1183sub grab_address_from_file($) {
1184 my ($file) = @_;
1185
1186 my $address;
1187
1188 # Check if the given file exists.
1189 if(-f $file) {
1190 # Open the file for reading.
1191 open(FILE, $file) or die "Could not read from $file. $!\n";
1192
1193 # Read the address from the file.
1194 $address = <FILE>;
1195
1196 # Close filehandle.
1197 close(FILE);
1198
1199 # Remove newlines.
1200 chomp($address);
1201
1202 # Check if the obtained address is valid.
1203 if (&validip($address)) {
1204 # Return the address.
1205 return $address;
1206 }
1207 }
1208
1209 # Return nothing.
1210 return;
1211}
1212
c8dcd465
SS
1213# Function to get all configured and enabled nameservers.
1214sub get_nameservers () {
1215 my %settings;
1216 my %servers;
1217
1218 my @nameservers;
1219
1220 # Read DNS configuration.
1221 &readhash("$General::swroot/dns/settings", \%settings);
1222
1223 # Read configured DNS servers.
1224 &readhasharray("$General::swroot/dns/servers", \%servers);
1225
1226 # Check if the ISP assigned server should be used.
1227 if ($settings{'USE_ISP_NAMESERVERS'} eq "on") {
1228 # Assign ISP nameserver files.
1229 my @ISP_nameserver_files = ( "/var/run/dns1", "/var/run/dns2" );
1230
1231 # Loop through the array of ISP assigned DNS servers.
1232 foreach my $file (@ISP_nameserver_files) {
1233 # Grab the IP address.
1234 my $address = &grab_address_from_file($file);
1235
1236 # Check if an address has been grabbed.
1237 if ($address) {
1238 # Add the address to the array of nameservers.
1239 push(@nameservers, $address);
1240 }
1241 }
1242 }
1243
1244 # Check if DNS servers are configured.
1245 if (%servers) {
1246 # Loop through the hash of configured DNS servers.
1247 foreach my $id (keys %servers) {
1248 my $address = $servers{$id}[0];
1249 my $status = $servers{$id}[2];
1250
1251 # Check if the current processed server is enabled.
1252 if ($status eq "enabled") {
1253 # Add the address to the array of nameservers.
1254 push(@nameservers, $address);
1255 }
1256 }
1257 }
1258
1259 # Return the array.
e8adbea9 1260 return &uniq(@nameservers);
c8dcd465
SS
1261}
1262
c5f85b11
SS
1263# Function to format a string containing the amount of bytes to
1264# something human-readable.
1265sub formatBytes {
1266 # Private array which contains the units.
1267 my @units = qw(B KB MB GB TB PB);
1268
1269 my $bytes = shift;
1270 my $unit;
1271
1272 # Loop through the array of units.
1273 foreach my $element (@units) {
25932be3
SS
1274 # Assign current processed element to unit.
1275 $unit = $element;
1276
c5f85b11
SS
1277 # Break loop if the bytes are less than the next unit.
1278 last if $bytes < 1024;
1279
1280 # Divide bytes amount with 1024.
1281 $bytes /= 1024;
c5f85b11
SS
1282 }
1283
1284 # Return the divided and rounded bytes count and the unit.
1285 return sprintf("%.2f %s", $bytes, $unit);
1286}
1287
4e58ab4b
MT
1288# Cloud Stuff
1289
46b0f9ab
MT
1290sub running_in_cloud() {
1291 return &running_on_ec2() || &running_on_gcp();
1292}
1293
4e58ab4b
MT
1294sub running_on_ec2() {
1295 if (-e "/var/run/aws-instance-id") {
1296 return 1;
1297 }
1298
1299 return 0;
1300}
1301
e7978f56
MT
1302sub running_on_gcp() {
1303 if (-e "/var/run/gcp-instance-id") {
1304 return 1;
1305 }
1306
1307 return 0;
1308}
1309
ac1cfefa 13101;