]> git.ipfire.org Git - people/teissler/ipfire-2.x.git/blame - config/cfgroot/general-functions.pl
OpenVPN ccd: fixed counter in static networks. Only 63 hosts are possible in /24...
[people/teissler/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
24$General::version = 'VERSION';
25$General::swroot = 'CONFIG_ROOT';
26$General::noipprefix = 'noipg-';
c545beb1 27$General::adminmanualurl = 'http://wiki.ipfire.org';
ac1cfefa 28
c545beb1
MT
29#
30# log ("message") use default 'ipcop' tag
31# log ("tag","message") use your tag
32#
ac1cfefa
MT
33sub log
34{
c545beb1
MT
35 my $tag='ipfire';
36 $tag = shift if (@_>1);
ac1cfefa
MT
37 my $logmessage = $_[0];
38 $logmessage =~ /([\w\W]*)/;
39 $logmessage = $1;
77007ce5 40 system('logger', '-t', $tag, $logmessage);
ac1cfefa
MT
41}
42
43sub readhash
44{
45 my $filename = $_[0];
46 my $hash = $_[1];
47 my ($var, $val);
48
49
50 # Some ipcop code expects that readhash 'complete' the hash if new entries
51 # are presents. Not clear it !!!
52 #%$hash = ();
53
54 open(FILE, $filename) or die "Unable to read file $filename";
55
56 while (<FILE>)
57 {
58 chop;
59 ($var, $val) = split /=/, $_, 2;
60 if ($var)
61 {
62 $val =~ s/^\'//g;
63 $val =~ s/\'$//g;
64
65 # Untaint variables read from hash
77007ce5
MT
66 # trim space from begin and end
67 $var =~ s/^\s+//;
68 $var =~ s/\s+$//;
69 $var =~ /([A-Za-z0-9_-]*)/;
70 $var = $1;
71 $val =~ /([\w\W]*)/;
72 $val = $1;
ac1cfefa
MT
73 $hash->{$var} = $val;
74 }
75 }
76 close FILE;
77}
78
79
80sub writehash
81{
82 my $filename = $_[0];
83 my $hash = $_[1];
84 my ($var, $val);
85
86 # write cgi vars to the file.
87 open(FILE, ">${filename}") or die "Unable to write file $filename";
88 flock FILE, 2;
89 foreach $var (keys %$hash)
90 {
ad60e3ea 91 if ( $var eq "__CGI__"){next;}
ac1cfefa
MT
92 $val = $hash->{$var};
93 # Darren Critchley Jan 17, 2003 added the following because when submitting with a graphic, the x and y
94 # location of the mouse are submitted as well, this was being written to the settings file causing
95 # some serious grief! This skips the variable.x and variable.y
96 if (!($var =~ /(.x|.y)$/)) {
97 if ($val =~ / /) {
98 $val = "\'$val\'"; }
99 if (!($var =~ /^ACTION/)) {
100 print FILE "${var}=${val}\n"; }
101 }
102 }
103 close FILE;
104}
105
90c2e164
CS
106sub writehashpart
107{
108 # This function replaces the given hash in the original hash by keeping the old
109 # content and just replacing the new content
110
111 my $filename = $_[0];
112 my $newhash = $_[1];
113 my %oldhash;
114 my ($var, $val);
115
116 readhash("${filename}", \%oldhash);
117
118 foreach $var (keys %$newhash){
119 $oldhash{$var}=$newhash->{$var};
120 }
121
122 # write cgi vars to the file.
123 open(FILE, ">${filename}") or die "Unable to write file $filename";
124 flock FILE, 2;
125 foreach $var (keys %oldhash)
126 {
127 if ( $var eq "__CGI__"){next;}
128 $val = $oldhash{$var};
129 # Darren Critchley Jan 17, 2003 added the following because when submitting with a graphic, the x and y
130 # location of the mouse are submitted as well, this was being written to the settings file causing
131 # some serious grief! This skips the variable.x and variable.y
132 if (!($var =~ /(.x|.y)$/)) {
133 if ($val =~ / /) {
134 $val = "\'$val\'"; }
135 if (!($var =~ /^ACTION/)) {
136 print FILE "${var}=${val}\n"; }
137 }
138 }
139 close FILE;
140}
ac1cfefa
MT
141
142sub age
143{
144 my ($dev, $ino, $mode, $nlink, $uid, $gid, $rdev, $size,
145 $atime, $mtime, $ctime, $blksize, $blocks) = stat $_[0];
146 my $now = time;
147
148 my $totalsecs = $now - $mtime;
149 my $days = int($totalsecs / 86400);
150 my $totalhours = int($totalsecs / 3600);
151 my $hours = $totalhours % 24;
152 my $totalmins = int($totalsecs / 60);
153 my $mins = $totalmins % 60;
154 my $secs = $totalsecs % 60;
155
156 return "${days}d ${hours}h ${mins}m ${secs}s";
157}
158
159sub validip
160{
161 my $ip = $_[0];
162
163 if (!($ip =~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/)) {
164 return 0; }
165 else
166 {
167 my @octets = ($1, $2, $3, $4);
168 foreach $_ (@octets)
169 {
170 if (/^0./) {
171 return 0; }
172 if ($_ < 0 || $_ > 255) {
173 return 0; }
174 }
175 return 1;
176 }
177}
178
179sub validmask
180{
181 my $mask = $_[0];
182
183 # secord part an ip?
184 if (&validip($mask)) {
185 return 1; }
186 # second part a number?
187 if (/^0/) {
188 return 0; }
189 if (!($mask =~ /^\d+$/)) {
190 return 0; }
191 if ($mask >= 0 && $mask <= 32) {
192 return 1; }
193 return 0;
194}
195
196sub validipormask
197{
198 my $ipormask = $_[0];
199
200 # see if it is a IP only.
201 if (&validip($ipormask)) {
202 return 1; }
203 # split it into number and mask.
204 if (!($ipormask =~ /^(.*?)\/(.*?)$/)) {
205 return 0; }
206 my $ip = $1;
207 my $mask = $2;
208 # first part not a ip?
209 if (!(&validip($ip))) {
210 return 0; }
211 return &validmask($mask);
212}
213
8c877a82 214sub subtocidr
ac1cfefa 215{
8c877a82
AM
216 #gets: Subnet in decimal (255.255.255.0)
217 #Gives: 24 (The cidr of network)
218 my ($byte1, $byte2, $byte3, $byte4) = split(/\./, $_[0].".0.0.0.0");
219 my $num = ($byte1 * 16777216) + ($byte2 * 65536) + ($byte3 * 256) + $byte4;
220 my $bin = unpack("B*", pack("N", $num));
221 my $count = ($bin =~ tr/1/1/);
222 return $count;
223}
ac1cfefa 224
8c877a82
AM
225sub cidrtosub
226{
227 #gets: Cidr of network (20-30 for ccd)
228 #Konverts 30 to 255.255.255.252 e.g
229 my $cidr=$_[0];
230 my $netmask = &Net::IPv4Addr::ipv4_cidr2msk($cidr);
231 return "$netmask";
232}
233
234sub iporsubtodec
235{
236 #Gets: Ip address or subnetmask in decimal oder CIDR
237 #Gives: What it gets only in CIDR format
238 my $subnet=$_[0];
239 my $net;
240 my $mask;
241 my $full=0;
242 if ($subnet =~ /^(.*?)\/(.*?)$/) {
243 ($net,$mask) = split (/\//,$subnet);
244 $full=1;
245 return "$subnet";
246 }else{
247 $mask=$subnet;
248 }
249 #Subnet already in decimal and valid?
250 if ($mask=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255 && $2<=$1 && $3<=$2 && $4<=$3 ))) {
251 for (my $i=8;$i<=32;$i++){
252 if (&General::cidrtosub($i) eq $mask){
253 if ($full == 0){return $mask;}else{
254 return $net."/".$mask;
255 }
256 }
257 }
258 }
259 #Subnet in binary format?
260 if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=8))){
261 if($full == 0){ return &General::cidrtosub($mask);}else{
262 return $net."/".&General::cidrtosub($mask);
263 }
264 }else{
265 return 3;
266 }
267 return 3;
268}
269
270
271sub iporsubtocidr
272{
273 #gets: Ip Address or subnetmask in decimal oder CIDR
274 #Gives: What it gets only in CIDR format
275 my $subnet=$_[0];
276 my $net;
277 my $mask;
278 my $full=0;
279 if ($subnet =~ /^(.*?)\/(.*?)$/) {
280 ($net,$mask) = split (/\//,$subnet);
281 $full=1;
282 }else{
283 $mask=$subnet;
284 }
285 #Subnet in decimal and valid?
286 if ($mask=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255 && $2<=$1 && $3<=$2 && $4<=$3 ))) {
287 for (my $i=8;$i<=32;$i++){
288 if (&General::cidrtosub($i) eq $mask){
289 if ($full == 0){return &General::subtocidr($mask);}else{
290 return $net."/".&General::subtocidr($mask);
291 }
292 }
293 }
294 }
295 #Subnet already in binary format?
296 if ($mask=~/^(\d{1,2})$/ && (($1<=32 && $1>=8))){
297 if($full == 0){ return $mask;}else{
298 return $net."/".$mask;
299 }
300 }else{
301 return 3;
302 }
303 return 3;
304}
305
306sub getnetworkip
307{
308 #Gets: IP, CIDR (10.10.10.0-255, 24)
309 #Gives: 10.10.10.0
310 my ($ccdip,$ccdsubnet) = @_;
311 my $ip_address_binary = inet_aton( $ccdip );
312 my $netmask_binary = ~pack("N", (2**(32-$ccdsubnet))-1);
313 my $network_address = inet_ntoa( $ip_address_binary & $netmask_binary );
314 return $network_address;
315}
316
317sub getccdbc
318{
319 #Gets: IP in Form ("192.168.0.0/24")
320 #Gives: Broadcastaddress of network
321 my $ccdnet=$_;
322 my ($ccdip,$ccdsubnet) = split "/",$ccdnet;
323 my $ip_address_binary = inet_aton( $ccdip );
324 my $netmask_binary = ~pack("N", (2**(32-$ccdsubnet))-1);
325 my $broadcast_address = inet_ntoa( $ip_address_binary | ~$netmask_binary );
326 return $broadcast_address;
327}
e81be1e1
AM
328
329sub ip2dec
330{
331 my $ip_num;
332 my $ip=$_[0];
333 if ( $ip =~ /(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})/ ) {
334 $ip_num = (($1*256**3) + ($2*256**2) + ($3*256) + $4);
335 } else {
336 $ip_num = -1;
337 }
338 $ip_num = (($1*256**3) + ($2*256**2) + ($3*256) + $4);
339 return($ip_num);
340}
341
342sub dec2ip
343{
344 my $ip;
345 my $ip_num=$_[0];
346 my $o1=$ip_num%256;
347 $ip_num=int($ip_num/256);
348 my $o2=$ip_num%256;
349 $ip_num=int($ip_num/256);
350 my $o3=$ip_num%256;
351 $ip_num=int($ip_num/256);
352 my $o4=$ip_num%256;
353 $ip="$o4.$o3.$o2.$o1";
354 return ($ip);
355}
356
8c877a82
AM
357sub getnextip
358{
e81be1e1
AM
359 my $decip=&ip2dec($_[0]);
360 $decip=$decip+4;
361 return &dec2ip($decip);
8c877a82 362}
e81be1e1 363
8c877a82
AM
364sub getlastip
365{
e81be1e1
AM
366 my $decip=&ip2dec($_[0]);
367 $decip--;
368 return &dec2ip($decip);
8c877a82
AM
369}
370
371sub validipandmask
372{
373 #Gets: Ip address in 192.168.0.0/24 or 192.168.0.0/255.255.255.0 and checks if subnet valid
374 #Gives: True bzw 0 if success or false
375 my $ccdnet=$_[0];
376 my $subcidr;
377
378 if (!($ccdnet =~ /^(.*?)\/(.*?)$/)) {
379 return 0;
380 }
381 my ($ccdip,$ccdsubnet)=split (/\//, $ccdnet);
382 #IP valid?
383 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 ))) {
384 #Subnet in decimal and valid?
385 if ($ccdsubnet=~/^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$/ &&(($1<=255 && $2<=$1 && $3<=$2 && $4<=$3 ))) {
290007b3 386 for (my $i=8;$i<=32;$i++){
8c877a82
AM
387 if (&General::cidrtosub($i) eq $ccdsubnet){
388 return 1;
389 }
390 }
391 #Subnet already in binary format?
290007b3 392 }elsif ($ccdsubnet=~/^(\d{1,2})$/ && (($1<=32 && $1>=8))){
8c877a82
AM
393 return 1;
394 }else{
395 return 0;
396 }
397
398 }
399 return 0;
ac1cfefa
MT
400}
401
402sub validport
403{
404 $_ = $_[0];
405
406 if (!/^\d+$/) {
407 return 0; }
408 if (/^0./) {
409 return 0; }
410 if ($_ >= 1 && $_ <= 65535) {
411 return 1; }
412 return 0;
413}
414
d30ea451
CS
415sub validproxyport
416{
417 $_ = $_[0];
418
419 if (!/^\d+$/) {
420 return 0; }
421 if (/^0./) {
422 return 0; }
423 if ($_ == 53 || $_ == 222 || $_ == 444 || $_ == 81 ) {
424 return 0; }
425 elsif ($_ >= 1 && $_ <= 65535) {
426 return 1; }
427 return 0;
428}
429
ac1cfefa
MT
430sub validmac
431{
432 my $checkmac = $_[0];
433 my $ot = '[0-9a-f]{2}'; # 2 Hex digits (one octet)
434 if ($checkmac !~ /^$ot:$ot:$ot:$ot:$ot:$ot$/i)
435 {
436 return 0;
437 }
438 return 1;
439}
440
441sub validhostname
442{
443 # Checks a hostname against RFC1035
444 my $hostname = $_[0];
445
446 # Each part should be at least two characters in length
447 # but no more than 63 characters
448 if (length ($hostname) < 1 || length ($hostname) > 63) {
449 return 0;}
450 # Only valid characters are a-z, A-Z, 0-9 and -
8c877a82 451 if ($hostname !~ /^[a-zA-Z0-9-\s]*$/) {
ac1cfefa
MT
452 return 0;}
453 # First character can only be a letter or a digit
454 if (substr ($hostname, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
455 return 0;}
456 # Last character can only be a letter or a digit
457 if (substr ($hostname, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
458 return 0;}
459 return 1;
460}
461
462sub validdomainname
463{
464 my $part;
465
466 # Checks a domain name against RFC1035
467 my $domainname = $_[0];
468 my @parts = split (/\./, $domainname); # Split hostname at the '.'
469
470 foreach $part (@parts) {
471 # Each part should be at least two characters in length
472 # but no more than 63 characters
473 if (length ($part) < 2 || length ($part) > 63) {
474 return 0;}
475 # Only valid characters are a-z, A-Z, 0-9 and -
476 if ($part !~ /^[a-zA-Z0-9-]*$/) {
477 return 0;}
478 # First character can only be a letter or a digit
479 if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
480 return 0;}
481 # Last character can only be a letter or a digit
482 if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
483 return 0;}
484 }
485 return 1;
486}
487
488sub validfqdn
489{
490 my $part;
491
492 # Checks a fully qualified domain name against RFC1035
493 my $fqdn = $_[0];
494 my @parts = split (/\./, $fqdn); # Split hostname at the '.'
495 if (scalar(@parts) < 2) { # At least two parts should
496 return 0;} # exist in a FQDN
497 # (i.e. hostname.domain)
498 foreach $part (@parts) {
499 # Each part should be at least one character in length
500 # but no more than 63 characters
501 if (length ($part) < 1 || length ($part) > 63) {
502 return 0;}
503 # Only valid characters are a-z, A-Z, 0-9 and -
504 if ($part !~ /^[a-zA-Z0-9-]*$/) {
505 return 0;}
506 # First character can only be a letter or a digit
507 if (substr ($part, 0, 1) !~ /^[a-zA-Z0-9]*$/) {
508 return 0;}
509 # Last character can only be a letter or a digit
510 if (substr ($part, -1, 1) !~ /^[a-zA-Z0-9]*$/) {
511 return 0;}
512 }
513 return 1;
514}
515
516sub validportrange # used to check a port range
517{
518 my $port = $_[0]; # port values
519 $port =~ tr/-/:/; # replace all - with colons just in case someone used -
520 my $srcdst = $_[1]; # is it a source or destination port
521
522 if (!($port =~ /^(\d+)\:(\d+)$/)) {
523
524 if (!(&validport($port))) {
525 if ($srcdst eq 'src'){
526 return $Lang::tr{'source port numbers'};
527 } else {
528 return $Lang::tr{'destination port numbers'};
529 }
530 }
531 }
532 else
533 {
534 my @ports = ($1, $2);
535 if ($1 >= $2){
536 if ($srcdst eq 'src'){
537 return $Lang::tr{'bad source range'};
538 } else {
539 return $Lang::tr{'bad destination range'};
540 }
541 }
542 foreach $_ (@ports)
543 {
544 if (!(&validport($_))) {
545 if ($srcdst eq 'src'){
546 return $Lang::tr{'source port numbers'};
547 } else {
548 return $Lang::tr{'destination port numbers'};
549 }
550 }
551 }
552 return;
553 }
554}
555
556# Test if IP is within a subnet
557# Call: IpInSubnet (Addr, Subnet, Subnet Mask)
558# Subnet can be an IP of the subnet: 10.0.0.0 or 10.0.0.1
559# Everything in dottted notation
560# Return: TRUE/FALSE
561sub IpInSubnet
562{
563 my $ip = unpack('N', &Socket::inet_aton(shift));
564 my $start = unpack('N', &Socket::inet_aton(shift));
565 my $mask = unpack('N', &Socket::inet_aton(shift));
566 $start &= $mask; # base of subnet...
567 my $end = $start + ~$mask;
568 return (($ip >= $start) && ($ip <= $end));
569}
570
c545beb1
MT
571#
572# Return the following IP (IP+1) in dotted notation.
573# Call: NextIP ('1.1.1.1');
574# Return: '1.1.1.2'
575#
576sub NextIP
577{
578 return &Socket::inet_ntoa( pack("N", 1 + unpack('N', &Socket::inet_aton(shift))
579 )
580 );
581}
8c877a82
AM
582sub NextIP2
583{
584 return &Socket::inet_ntoa( pack("N", 4 + unpack('N', &Socket::inet_aton(shift))
585 )
586 );
587}
45762fc6
AF
588sub ipcidr
589{
590 my ($ip,$cidr) = &Net::IPv4Addr::ipv4_parse(shift);
591 return "$ip\/$cidr";
592}
593
54fd0535
MT
594sub ipcidr2msk
595{
596 my ($ip,$cidr) = &Net::IPv4Addr::ipv4_parse(shift);
597 my $netmask = &Net::IPv4Addr::ipv4_cidr2msk($cidr);
598 return "$ip\/$netmask";
599}
600
601
ac1cfefa
MT
602sub validemail {
603 my $mail = shift;
604 return 0 if ( $mail !~ /^[0-9a-zA-Z\.\-\_]+\@[0-9a-zA-Z\.\-]+$/ );
605 return 0 if ( $mail =~ /^[^0-9a-zA-Z]|[^0-9a-zA-Z]$/);
606 return 0 if ( $mail !~ /([0-9a-zA-Z]{1})\@./ );
607 return 0 if ( $mail !~ /.\@([0-9a-zA-Z]{1})/ );
608 return 0 if ( $mail =~ /.\.\-.|.\-\..|.\.\..|.\-\-./g );
609 return 0 if ( $mail =~ /.\.\_.|.\-\_.|.\_\..|.\_\-.|.\_\_./g );
610 return 0 if ( $mail !~ /\.([a-zA-Z]{2,4})$/ );
611 return 1;
612}
613
c545beb1
MT
614#
615# Currently only vpnmain use this three procs (readhasharray, writehasharray, findhasharray)
616# The 'key' used is numeric but is perfectly unneeded! This will to be removed so don't use
617# this code. Vpnmain will be splitted in parts: x509/pki, connection ipsec, connection other,... .
618#
ac1cfefa
MT
619sub readhasharray {
620 my ($filename, $hash) = @_;
621 %$hash = ();
622
623 open(FILE, $filename) or die "Unable to read file $filename";
624
625 while (<FILE>) {
626 my ($key, $rest, @temp);
627 chomp;
628 ($key, $rest) = split (/,/, $_, 2);
c545beb1 629 if ($key =~ /^[0-9]+$/) {
ac1cfefa
MT
630 @temp = split (/,/, $rest);
631 $hash->{$key} = \@temp;
632 }
633 }
634 close FILE;
635 return;
636}
637
638sub writehasharray {
639 my ($filename, $hash) = @_;
640 my ($key, @temp, $i);
641
642 open(FILE, ">$filename") or die "Unable to write to file $filename";
643
644 foreach $key (keys %$hash) {
8c877a82
AM
645 if ($key =~ /^[0-9]+$/) {
646 print FILE "$key";
647 foreach $i (0 .. $#{$hash->{$key}}) {
648 print FILE ",$hash->{$key}[$i]";
649 }
650 print FILE "\n";
651 }
ac1cfefa
MT
652 }
653 close FILE;
654 return;
655}
656
657sub findhasharraykey {
658 foreach my $i (1 .. 1000000) {
659 if ( ! exists $_[0]{$i}) {
660 return $i;
661 }
662 }
663}
664
665sub srtarray
666# Darren Critchley - darrenc@telus.net - (c) 2003
667# &srtarray(SortOrder, AlphaNumeric, SortDirection, ArrayToBeSorted)
668# This subroutine will take the following parameters:
669# ColumnNumber = the column which you want to sort on, starts at 1
670# AlphaNumberic = a or n (lowercase) defines whether the sort should be alpha or numberic
671# SortDirection = asc or dsc (lowercase) Ascending or Descending sort
672# ArrayToBeSorted = the array that wants sorting
673#
674# Returns an array that is sorted to your specs
675#
676# If SortOrder is greater than the elements in array, then it defaults to the first element
677#
678{
679 my ($colno, $alpnum, $srtdir, @tobesorted) = @_;
680 my @tmparray;
681 my @srtedarray;
682 my $line;
683 my $newline;
684 my $ctr;
685 my $ttlitems = scalar @tobesorted; # want to know the number of rows in the passed array
686 if ($ttlitems < 1){ # if no items, don't waste our time lets leave
687 return (@tobesorted);
688 }
689 my @tmp = split(/\,/,$tobesorted[0]);
690 $ttlitems = scalar @tmp; # this should be the number of elements in each row of the passed in array
691
692 # Darren Critchley - validate parameters
693 if ($colno > $ttlitems){$colno = '1';}
694 $colno--; # remove one from colno to deal with arrays starting at 0
695 if($colno < 0){$colno = '0';}
696 if ($alpnum ne '') { $alpnum = lc($alpnum); } else { $alpnum = 'a'; }
697 if ($srtdir ne '') { $srtdir = lc($srtdir); } else { $srtdir = 'src'; }
698
699 foreach $line (@tobesorted)
700 {
701 chomp($line);
702 if ($line ne '') {
703 my @temp = split(/\,/,$line);
704 # Darren Critchley - juggle the fields so that the one we want to sort on is first
705 my $tmpholder = $temp[0];
706 $temp[0] = $temp[$colno];
707 $temp[$colno] = $tmpholder;
708 $newline = "";
709 for ($ctr=0; $ctr < $ttlitems ; $ctr++) {
710 $newline=$newline . $temp[$ctr] . ",";
711 }
712 chop($newline);
713 push(@tmparray,$newline);
714 }
715 }
716 if ($alpnum eq 'n') {
717 @tmparray = sort {$a <=> $b} @tmparray;
718 } else {
719 @tmparray = (sort @tmparray);
720 }
721 foreach $line (@tmparray)
722 {
723 chomp($line);
724 if ($line ne '') {
725 my @temp = split(/\,/,$line);
726 my $tmpholder = $temp[0];
727 $temp[0] = $temp[$colno];
728 $temp[$colno] = $tmpholder;
729 $newline = "";
730 for ($ctr=0; $ctr < $ttlitems ; $ctr++){
731 $newline=$newline . $temp[$ctr] . ",";
732 }
733 chop($newline);
734 push(@srtedarray,$newline);
735 }
736 }
737
738 if ($srtdir eq 'dsc') {
739 @tmparray = reverse(@srtedarray);
740 return (@tmparray);
741 } else {
742 return (@srtedarray);
743 }
744}
745
746sub FetchPublicIp {
747 my %proxysettings;
748 &General::readhash("${General::swroot}/proxy/settings", \%proxysettings);
749 if ($_=$proxysettings{'UPSTREAM_PROXY'}) {
750 my ($peer, $peerport) = (/^(?:[a-zA-Z ]+\:\/\/)?(?:[A-Za-z0-9\_\.\-]*?(?:\:[A-Za-z0-9\_\.\-]*?)?\@)?([a-zA-Z0-9\.\_\-]*?)(?:\:([0-9]{1,5}))?(?:\/.*?)?$/);
751 Net::SSLeay::set_proxy($peer,$peerport,$proxysettings{'UPSTREAM_USER'},$proxysettings{'UPSTREAM_PASSWORD'} );
752 }
753 my ($out, $response) = Net::SSLeay::get_http( 'checkip.dyndns.org',
754 80,
755 "/",
39a7cc11 756 Net::SSLeay::make_headers('User-Agent' => 'IPFire' )
ac1cfefa
MT
757 );
758 if ($response =~ m%HTTP/1\.. 200 OK%) {
759 $out =~ /Current IP Address: (\d+.\d+.\d+.\d+)/;
760 return $1;
761 }
762 return '';
763}
764
765#
766# Check if hostname.domain provided have IP provided
767# use gethostbyname to verify that
768# Params:
769# IP
770# hostname
771# domain
772# Output
773# 1 IP matches host.domain
774# 0 not in sync
775#
776sub DyndnsServiceSync ($;$;$) {
777
778 my ($ip,$hostName,$domain) = @_;
779 my @addresses;
780
781 #fix me no ip GROUP, what is the name ?
782 $hostName =~ s/$General::noipprefix//;
783 if ($hostName) { #may be empty
784 $hostName = "$hostName.$domain";
785 @addresses = gethostbyname($hostName);
786 }
787
788 if ($addresses[0] eq '') { # nothing returned ?
789 $hostName = $domain; # try resolving with domain only
790 @addresses = gethostbyname($hostName);
791 }
792
793 if ($addresses[0] ne '') { # got something ?
794 #&General::log("name:$addresses[0], alias:$addresses[1]");
795 # Build clear text list of IP
796 @addresses = map ( &Socket::inet_ntoa($_), @addresses[4..$#addresses]);
797 if (grep (/$ip/, @addresses)) {
798 return 1;
799 }
800 }
801 return 0;
802}
803#
804# This sub returns the red IP used to compare in DyndnsServiceSync
805#
806sub GetDyndnsRedIP {
807 my %settings;
808 &General::readhash("${General::swroot}/ddns/settings", \%settings);
809
810 open(IP, "${General::swroot}/red/local-ipaddress") or return 'unavailable';
811 my $ip = <IP>;
812 close(IP);
813 chomp $ip;
814
815 if (&General::IpInSubnet ($ip,'10.0.0.0','255.0.0.0') ||
816 &General::IpInSubnet ($ip,'172.16.0.0.','255.240.0.0') ||
817 &General::IpInSubnet ($ip,'192.168.0.0','255.255.0.0'))
818 {
819 if ($settings{'BEHINDROUTER'} eq 'FETCH_IP') {
820 my $RealIP = &General::FetchPublicIp;
821 $ip = (&General::validip ($RealIP) ? $RealIP : 'unavailable');
822 }
823 }
824 return $ip;
825}
c545beb1
MT
826
827# Translate ICMP code to text
828# ref: http://www.iana.org/assignments/icmp-parameters
829sub GetIcmpDescription ($) {
830 my $index = shift;
831 my @icmp_description = (
832 'Echo Reply', #0
833 'Unassigned',
834 'Unassigned',
835 'Destination Unreachable',
836 'Source Quench',
837 'Redirect',
838 'Alternate Host Address',
839 'Unassigned',
840 'Echo',
841 'Router Advertisement',
842 'Router Solicitation', #10
843 'Time Exceeded',
844 'Parameter Problem',
845 'Timestamp',
846 'Timestamp Reply',
847 'Information Request',
848 'Information Reply',
849 'Address Mask Request',
850 'Address Mask Reply',
851 'Reserved (for Security)',
852 'Reserved (for Robustness Experiment)', #20
853 'Reserved',
854 'Reserved',
855 'Reserved',
856 'Reserved',
857 'Reserved',
858 'Reserved',
859 'Reserved',
860 'Reserved',
861 'Reserved',
862 'Traceroute', #30
863 'Datagram Conversion Error',
864 'Mobile Host Redirect',
865 'IPv6 Where-Are-You',
866 'IPv6 I-Am-Here',
867 'Mobile Registration Request',
868 'Mobile Registration Reply',
869 'Domain Name Request',
870 'Domain Name Reply',
871 'SKIP',
872 'Photur', #40
873 'Experimental');
874 if ($index>41) {return 'unknown'} else {return @icmp_description[$index]};
875}
ac1cfefa 8761;