]> git.ipfire.org Git - ipfire-2.x.git/blobdiff - html/cgi-bin/services.cgi
SMP-Config angepasst.. CGIs usw. wurden im Windoof-Format gespeichert... muss noch...
[ipfire-2.x.git] / html / cgi-bin / services.cgi
index 688cdc9c05adb2cce1acfe8d0c8c032c38612752..9a1c016a8266a53550da56a18f3edb3ed3cf5630 100644 (file)
-#!/usr/bin/perl\r
-#\r
-# This file is part of the IPCop Firewall.\r
-#\r
-# IPCop is free software; you can redistribute it and/or modify\r
-# it under the terms of the GNU General Public License as published by\r
-# the Free Software Foundation; either version 2 of the License, or\r
-# (at your option) any later version.\r
-#\r
-# IPCop is distributed in the hope that it will be useful,\r
-# but WITHOUT ANY WARRANTY; without even the implied warranty of\r
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\r
-# GNU General Public License for more details.\r
-#\r
-# You should have received a copy of the GNU General Public License\r
-# along with IPCop; if not, write to the Free Software\r
-# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA\r
-#\r
-# Copyright (C) 2003-09-22 Darren Critchley <darrenc@telus.net>\r
-#\r
-# $Id: services.cgi,v 1.2.2.3 2005/04/29 23:37:07 franck78 Exp $\r
-#\r
-\r
-use strict;\r
-\r
-require 'CONFIG_ROOT/general-functions.pl';\r
-require "${General::swroot}/lang.pl";\r
-require "${General::swroot}/header.pl";\r
-\r
-my @icmptypes = &get_icmptypes();\r
-\r
-&Header::showhttpheaders();\r
-\r
-my %cgiparams=();\r
-my %selected=();\r
-my %checked=();\r
-my $filename = "${General::swroot}/firewall/customservices";\r
-my $key = 0; # used for finding last sequence number used \r
-\r
-# Darren Critchley - vars for setting up sort order\r
-my $sort_col = '1';\r
-my $sort_type = 'a';\r
-my $sort_dir = 'asc';\r
-\r
-if ($ENV{'QUERY_STRING'} ne '') {\r
-       my ($item1, $item2, $item3) = split(/\&/,$ENV{'QUERY_STRING'});\r
-       if ($item1 ne '') {\r
-               ($junk, $sort_col) = split(/\=/,$item1)\r
-       }\r
-       if ($item2 ne '') {\r
-               ($junk, $sort_type) = split(/\=/,$item2)\r
-       }\r
-       if ($item3 ne '') {\r
-               ($junk, $sort_dir) = split(/\=/,$item3)\r
-       }\r
-}\r
-\r
-$cgiparams{'KEY'} = '';\r
-$cgiparams{'PORTS'} = '';\r
-$cgiparams{'PROTOCOL'} = '6';\r
-$cgiparams{'NAME'} = '';\r
-$cgiparams{'PORT_INVERT'} = 'off';\r
-$cgiparams{'PROTOCOL_INVERT'} = 'off';\r
-$cgiparams{'ICMP'} = 'BLANK';\r
-\r
-&Header::getcgihash(\%cgiparams);\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'add'}){\r
-\r
-       &validateparams();\r
-       unless($errormessage){\r
-               $key++; # Add one to last sequence number\r
-               open(FILE,">>$filename") or die 'Unable to open config file.';\r
-               flock FILE, 2;\r
-               print FILE "$key,$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";\r
-               close(FILE);\r
-               &General::log("$Lang::tr{'service added'}: $cgiparams{'NAME'}");\r
-               undef %cgiparams;\r
-       }\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'update'})\r
-{\r
-       &validateparams();\r
-       # Darren Critchley - If there is an error don't waste any more processing time\r
-       if ($errormessage) { $cgiparams{'ACTION'} = $Lang::tr{'edit'}; goto UPD_ERROR; }\r
-\r
-       unless($errormessage){\r
-               open(FILE, $filename) or die 'Unable to open custom services file.';\r
-               my @current = <FILE>;\r
-               close(FILE);\r
-               my $line;\r
-               open(FILE, ">$filename") or die 'Unable to open config file.';\r
-               flock FILE, 2;\r
-               foreach $line (@current) {\r
-                       chomp($line);\r
-                       my @temp = split(/\,/,$line);\r
-                       if ($cgiparams{'KEY'} eq $temp[0]) {\r
-                               print FILE "$cgiparams{'KEY'},$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";\r
-                       } else {\r
-                               print FILE "$line\n";\r
-                       }\r
-               }\r
-               close(FILE);\r
-               &General::log("$Lang::tr{'service updated'}: $cgiparams{'NAME'}");\r
-               undef %cgiparams;\r
-       }\r
-UPD_ERROR:\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'})\r
-{\r
-       open(FILE, "$filename") or die 'Unable to open custom services file.';\r
-       my @current = <FILE>;\r
-       close(FILE);\r
-\r
-       unless ($errormessage)\r
-       {\r
-               foreach my $line (@current)\r
-               {\r
-                       chomp($line);\r
-                       my @temp = split(/\,/,$line);\r
-                       if ($cgiparams{'KEY'} eq $temp[0]) {\r
-                               $cgiparams{'NAME'} = $temp[1];\r
-                               $cgiparams{'PORTS'} = $temp[2];\r
-                               $cgiparams{'PROTOCOL'} = $temp[3];\r
-                               $cgiparams{'PORT_INVERT'} = $temp[4];\r
-                               $cgiparams{'PROTOCOL_INVERT'} = $temp[5];\r
-                               $cgiparams{'ICMP'} = $temp[6];\r
-                       }\r
-                       \r
-               }\r
-       }\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'remove'})\r
-{\r
-       open(FILE, $filename) or die 'Unable to open custom services file.';\r
-       my @current = <FILE>;\r
-       close(FILE);\r
-\r
-       open(FILE, ">$filename") or die 'Unable to open custom services file.';\r
-       flock FILE, 2;\r
-       foreach my $line (@current)\r
-       {\r
-               chomp($line);\r
-               if ($line ne '') {              \r
-                       my @temp = split(/\,/,$line);\r
-                       if ($cgiparams{'KEY'} eq $temp[0]) {\r
-                               &General::log("$Lang::tr{'service removed'}: $temp[1]");\r
-                       } else {\r
-                                       print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6]\n";\r
-                       }\r
-               }\r
-       }\r
-       close(FILE);\r
-       undef %cgiparams;\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'reset'})\r
-{\r
-       undef %cgiparams;\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq '')\r
-{\r
-       $cgiparams{'KEY'} = '';\r
-       $cgiparams{'PORTS'} = '';\r
-       $cgiparams{'PROTOCOL'} = '6';\r
-    $cgiparams{'NAME'} = '';\r
-       $cgiparams{'PORT_INVERT'} = 'off';\r
-       $cgiparams{'PROTOCOL_INVERT'} = 'off';\r
-       $cgiparams{'ICMP'} = 'BLANK';\r
-}\r
-\r
-# Darren Critchley - Bring in the protocols file built from /etc/protocols into hash %protocol\r
-require "${General::swroot}/firewall/protocols.pl";\r
-\r
-# Darren Critchley - figure out which protocol is selected\r
-$selected{'PROTOCOL'}{'tcpudp'}= '';\r
-$selected{'PROTOCOL'}{'all'}= '';\r
-foreach $line (keys %protocols) {\r
-#      $selected{'PROTOCOL'}{"$protocols{$line}"}= '';\r
-       $selected{'PROTOCOL'}{$line}= '';\r
-}\r
-$selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = 'SELECTED';\r
-\r
-# Darren Critchley - figure out which icmptype is selected\r
-$selected{'ICMP'}{$cgiparams{'ICMP'}} = 'SELECTED';\r
-\r
-$checked{'PORT_INVERT'}{'off'} = '';\r
-$checked{'PORT_INVERT'}{'on'} = '';\r
-$checked{'PORT_INVERT'}{$cgiparams{'PORT_INVERT'}} = 'CHECKED';\r
-$checked{'PROTOCOL_INVERT'}{'off'} = '';\r
-$checked{'PROTOCOL_INVERT'}{'on'} = '';\r
-$checked{'PROTOCOL_INVERT'}{$cgiparams{'PROTOCOL_INVERT'}} = 'CHECKED';\r
-\r
-&Header::openpage($Lang::tr{'services settings'}, 1, '');\r
-\r
-&Header::openbigbox('100%', 'LEFT', '', $errormessage);\r
-\r
-# DEBUG DEBUG\r
-#&Header::openbox('100%', 'LEFT', 'DEBUG');\r
-#foreach $line (keys %cgiparams) {\r
-#      print "<CLASS NAME='base'>$line = $cgiparams{$line}<BR>";\r
-#}\r
-#print "$sort_col\n";\r
-#print "$ENV{'QUERY_STRING'}\n";\r
-#print "&nbsp;</CLASS>\n";\r
-#&Header::closebox();\r
-\r
-if ($errormessage) {\r
-       &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});\r
-       print "<CLASS NAME='base'><FONT COLOR='${Header::colourred}'>$errormessage\n</FONT>";\r
-       print "&nbsp;</CLASS>\n";\r
-       &Header::closebox();\r
-}\r
-\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){\r
-       &Header::openbox('100%', 'LEFT', "$Lang::tr{'edit service'}:");\r
-} else {\r
-       &Header::openbox('100%', 'LEFT', "$Lang::tr{'add service'}:");\r
-}\r
-# Darren Critchley - Show protocols with TCP, UDP, etc at the top of the list.\r
-print <<END\r
-<FORM METHOD='POST'>\r
-<DIV ALIGN='CENTER'>\r
-<TABLE WIDTH='100%' ALIGN='CENTER'>\r
-<TR align="center">\r
-       <TD><strong>$Lang::tr{'servicename'}</strong></TD>\r
-       <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>\r
-       <TD><strong>$Lang::tr{'ports'}</strong></TD>\r
-       <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>\r
-       <TD><strong>$Lang::tr{'protocol'}</strong></TD>\r
-       <TD>&nbsp;</TD>\r
-       <TD>&nbsp;</TD>\r
-</TR>\r
-<TR align="center">\r
-       <TD>\r
-               <INPUT TYPE='TEXT' NAME='NAME' VALUE='$cgiparams{'NAME'}' SIZE='20' MAXLENGTH='20'>\r
-       </TD>\r
-       <TD ALIGN='RIGHT'>\r
-               <INPUT TYPE='CHECKBOX' NAME='PORT_INVERT' $checked{'PORT_INVERT'}{'on'}>\r
-       </TD>\r
-       <TD>\r
-               <INPUT TYPE='TEXT' NAME='PORTS' VALUE='$cgiparams{'PORTS'}' SIZE='15' MAXLENGTH='11'>\r
-       </TD>\r
-       <TD ALIGN='RIGHT'>\r
-               <INPUT TYPE='CHECKBOX' NAME='PROTOCOL_INVERT' $checked{'PROTOCOL_INVERT'}{'on'}>\r
-       </TD>\r
-    <TD ALIGN='LEFT'>\r
-               <SELECT NAME='PROTOCOL'>\r
-                       <OPTION VALUE='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</OPTION>\r
-                       <OPTION VALUE='udp' $selected{'PROTOCOL'}{'udp'}>UDP</OPTION>\r
-                       <OPTION VALUE='tcpudp' $selected{'PROTOCOL'}{'tcpudp'}>TCP & UDP</OPTION>\r
-                       <OPTION VALUE='all' $selected{'PROTOCOL'}{'all'}>ALL</OPTION>\r
-                       <OPTION VALUE='icmp' $selected{'PROTOCOL'}{'icmp'}>ICMP</OPTION>\r
-                       <OPTION VALUE='gre' $selected{'PROTOCOL'}{'gre'}>GRE</OPTION>\r
-END\r
-;\r
-foreach $line (sort keys %protocols) {\r
-       # Darren Critchley - do not have duplicates in the list\r
-       if ($protocols{$line} ne '6' && $protocols{$line} ne '17' && $protocols{$line} ne '1' && $protocols{$line} ne '47'){\r
-#              print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$protocols{$line}}>".uc($line)."</OPTION>\n";\r
-               print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$line}>".uc($line)."</OPTION>\n";\r
-       }\r
-}\r
-print <<END\r
-               </SELECT>\r
-       </TD>\r
-</TR>\r
-<TR>\r
-       <TD>&nbsp;</TD>\r
-       <TD>&nbsp;</TD>\r
-       <TD>&nbsp;</TD>\r
-       <TD><strong>$Lang::tr{'icmp type'}:</strong></TD>\r
-       <TD ALIGN='LEFT'>\r
-                       <SELECT NAME='ICMP'>\r
-                               <OPTION VALUE='BLANK' $selected{'ICMP'}{'BLANK'}>Valid ICMP Types</OPTION>\r
-END\r
-;\r
-foreach $line (@icmptypes) {\r
-       if ($cgiparams{'ICMP'} eq $line){\r
-               print "<OPTION VALUE='$line' SELECTED>$line</OPTION>\n";\r
-       } else {\r
-               print "<OPTION VALUE='$line' >$line</OPTION>\n";\r
-       }\r
-}\r
-print <<END\r
-                       </SELECT>\r
-       </TD>\r
-</TR>\r
-<TR>\r
-END\r
-;\r
-if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){\r
-       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'update'}'></TD>\n";\r
-       print "<INPUT TYPE='HIDDEN' NAME='KEY' VALUE='$cgiparams{'KEY'}'>\n";\r
-       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";\r
-} else {\r
-       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'add'}'></TD>\n";\r
-       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";\r
-}\r
-print <<END\r
-</TR>\r
-</TABLE>\r
-</DIV>\r
-</FORM>\r
-END\r
-;\r
-\r
-&Header::closebox();\r
-\r
-&Header::openbox('100%', 'LEFT', "$Lang::tr{'custom services'}:");\r
-print <<END\r
-<DIV ALIGN='CENTER'>\r
-<TABLE WIDTH='100%' ALIGN='CENTER'>\r
-<TR align="center">\r
-END\r
-;\r
-\r
-if ($sort_dir eq 'asc' && $sort_col eq '2') {\r
-       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=2&srtype=a&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'servicename'}</a></strong></TD>\n";\r
-} else {\r
-       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=2&srtype=a&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'servicename'}</a></strong></TD>\n";\r
-}\r
-if ($sort_dir eq 'asc' && $sort_col eq '3') {\r
-       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=3&srtype=n&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'ports'}</a></strong></TD>\n";\r
-} else {\r
-       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=3&srtype=n&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'ports'}</a></strong></TD>\n";\r
-}\r
-if ($sort_dir eq 'asc' && $sort_col eq '4') {\r
-       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=4&srtype=a&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'protocol'}</a></strong></TD>\n";\r
-} else {\r
-       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=4&srtype=a&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'protocol'}</a></strong></TD>\n";\r
-}\r
-\r
-print <<END\r
-       <TD WIDTH='25%'><strong>$Lang::tr{'icmp type'}</strong></TD>\r
-       <TD WIDTH='5%'>&nbsp;</TD>\r
-       <TD WIDTH='5%'>&nbsp;</TD>\r
-</TR>\r
-END\r
-;\r
-&display_custom_services();\r
-print <<END\r
-</TABLE>\r
-</DIV>\r
-END\r
-;\r
-&Header::closebox();\r
-\r
-&Header::openbox('100%', 'LEFT', "$Lang::tr{'default services'}:");\r
-print <<END\r
-<DIV ALIGN='CENTER'>\r
-<TABLE WIDTH='100%' ALIGN='CENTER'>\r
-<TR align="center">\r
-       <TD><strong>$Lang::tr{'servicename'}</strong></TD>\r
-       <TD><strong>$Lang::tr{'ports'}</strong></TD>\r
-       <TD><strong>$Lang::tr{'protocol'}</strong></TD>\r
-</TR>\r
-END\r
-;\r
-&display_default_services();\r
-print <<END\r
-</TABLE>\r
-</DIV>\r
-END\r
-;\r
-&Header::closebox();\r
\r
-    print "$Lang::tr{'this feature has been sponsored by'} : ";\r
-    print "<A HREF='http://www.kdi.ca/' TARGET='_blank'>Kobelt Development Inc.</A>.\n";\r
-\r
-\r
-&Header::closebigbox();\r
-\r
-&Header::closepage();\r
-\r
-sub display_custom_services\r
-{\r
-       \r
-       open(FILE, "$filename") or die 'Unable to open services file.';\r
-       my @current = <FILE>;\r
-       close(FILE);\r
-\r
-       my $id = 0;\r
-       my $port_inv = '';\r
-       my $prot_inv = '';\r
-       my $port_inv_tail = '';\r
-       my $prot_inv_tail = '';\r
-       my @outarray = &General::srtarray($sort_col,$sort_type,$sort_dir,@current);\r
-       foreach $line (@outarray)\r
-       {\r
-               chomp($line);\r
-               if ($line ne ''){\r
-                       my @temp = split(/\,/,$line);\r
-                       # Darren Critchley highlight the row we are editing\r
-                       if ( $cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'KEY'} eq $temp[0] ) { \r
-                               print "<TR BGCOLOR='${Header::colouryellow}'>\n";\r
-                       } else {\r
-                               if ($id % 2) {\r
-                                       print "<TR BGCOLOR='${Header::table1colour}'>\n"; \r
-                               } else {\r
-                       print "<TR BGCOLOR='${Header::table2colour}'>\n";\r
-                               }\r
-                       }\r
-                       print "<TD>$temp[1]</TD>\n";\r
-                       if ($temp[4] eq 'on'){$port_inv = " <strong><font color='RED'>! (</font></strong>";$port_inv_tail = "<strong><font color='RED'>)</font></strong>";}else{$port_inv='';$port_inv_tail='';}\r
-                       print "<TD ALIGN='CENTER'>" . $port_inv . &cleanport("$temp[2]") . $port_inv_tail . "</TD>\n";\r
-                       if ($temp[5] eq 'on'){$prot_inv = " <strong><font color='RED'>! (</font></strong>";$prot_inv_tail = "<strong><font color='RED'>)</font></strong>";}else{$prot_inv='';$prot_inv_tail='';}\r
-                       print "<TD ALIGN='CENTER'>" . $prot_inv . &cleanprotocol("$temp[3]") . $prot_inv_tail . "</TD>\n";\r
-                       if ($temp[6] eq 'BLANK') {\r
-                               print "<TD ALIGN='CENTER'>N/A</TD>\n";\r
-                       } else {\r
-                               print "<TD ALIGN='CENTER'>$temp[6]</TD>\n";\r
-                       }\r
-                       print <<END\r
-<FORM METHOD='POST' NAME='frm$temp[0]'>\r
-<TD ALIGN='CENTER'>\r
-       <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'edit'}'>\r
-       <INPUT TYPE='image' NAME='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'>\r
-       <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>\r
-</TD>\r
-</FORM>\r
-<FORM METHOD='POST' NAME='frm$temp[0]b'>\r
-<TD ALIGN='CENTER'>\r
-       <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'remove'}'>\r
-       <INPUT TYPE='image' NAME='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0'>\r
-       <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>\r
-</TD>\r
-</FORM>\r
-END\r
-;\r
-                       print "</TR>\n";\r
-                       $id++;\r
-               }\r
-       }\r
-}\r
-\r
-sub display_default_services\r
-{\r
-       my $fname = "${General::swroot}/firewall/defaultservices";\r
-       my $prev = "";\r
-       my $newline="";\r
-       \r
-       open(FILE, "$fname") or die 'Unable to open default services file.';\r
-       my @current = <FILE>;\r
-       close(FILE);\r
-       \r
-       my $id = 0;\r
-       \r
-       foreach my $line (sort @current)\r
-       {\r
-               my @temp = split(/\,/,$line);\r
-               if ($id % 2) {\r
-                       print "<TR BGCOLOR='${Header::table1colour}'>\n"; \r
-               } else {\r
-               print "<TR BGCOLOR='${Header::table2colour}'>\n";\r
-               }\r
-               print "<TD>$temp[0]</TD>\n";\r
-               print "<TD ALIGN='CENTER'>$temp[1]</TD>\n";\r
-               print "<TD ALIGN='CENTER'>" . &cleanprotocol("$temp[2]") . "</TD>\n";\r
-               print "</TR>\n";\r
-               $id++;\r
-       }\r
-}\r
-\r
-sub cleanprotocol\r
-{\r
-       my $prtcl = $_[0];\r
-       chomp($prtcl);\r
-       if ($prtcl eq 'tcpudp') {\r
-               $prtcl = 'TCP & UDP';\r
-       } else {\r
-               $prtcl = uc($prtcl);\r
-       }\r
-       return $prtcl;\r
-}\r
-\r
-sub cleanport\r
-{\r
-       my $prt = $_[0];\r
-       chomp($prt);\r
-       # Darren Critchley - Format the ports\r
-       $prt =~ s/-/ - /;\r
-       $prt =~ s/:/ - /;\r
-       return $prt;\r
-}\r
-\r
-# Validate Field Entries\r
-sub validateparams \r
-{\r
-       $erromessage='';\r
-       if ($cgiparams{'PROTOCOL'} eq 'tcp' || $cgiparams{'PROTOCOL'} eq 'udp' || $cgiparams{'PROTOCOL'} eq 'tcpudp' || $cgiparams{'PROTOCOL'} eq 'all') {\r
-               # Darren Critchley - Get rid of dashes in port ranges\r
-               $cgiparams{'PORTS'}=~ tr/-/:/;\r
-               # Darren Critchley - code to substitue wildcards\r
-               if ($cgiparams{'PORTS'} eq "*") {\r
-                       $cgiparams{'PORTS'} = "1:65535";\r
-               }\r
-               if ($cgiparams{'PORTS'} =~ /^(\D)\:(\d+)$/) {\r
-                       $cgiparams{'PORTS'} = "1:$2";\r
-               }\r
-               if ($cgiparams{'PORTS'} =~ /^(\d+)\:(\D)$/) {\r
-                       $cgiparams{'PORTS'} = "$1:65535";\r
-               }\r
-               # Darren Critchley - watch the order here, the validportrange sets errormessage=''\r
-               $errormessage = &General::validportrange($cgiparams{'PORTS'}, 'src');\r
-               if ($errormessage) {return;}\r
-       } else {\r
-               $cgiparams{'PORTS'} = "";\r
-       }\r
-       if ($cgiparams{'PROTOCOL'} eq 'tcp') {\r
-               $cgiparams{'ICMP'} = "BLANK";\r
-       }\r
-       \r
-       if($cgiparams{'PORTS'} eq '' && $cgiparams{'PORT_INVERT'} ne 'off'){\r
-               $cgiparams{'PORT_INVERT'} = 'off';\r
-       }\r
-       if ($cgiparams{'NAME'} eq '') {\r
-               $errormessage = $Lang::tr{'noservicename'};\r
-               return;\r
-       }\r
-       if ($cgiparams{'PROTOCOL'} eq 'icmp' && $cgiparams{'ICMP'} eq 'BLANK'){\r
-               $errormessage = $Lang::tr{'icmp selected but no type'};\r
-               return;\r
-       }\r
-    unless($errormessage){\r
-               $cgiparams{'NAME'}=&Header::cleanhtml($cgiparams{'NAME'});\r
-               open(FILE, $filename) or die 'Unable to open custom services file.';\r
-               my @current = <FILE>;\r
-               close(FILE);\r
-               foreach my $line (@current)\r
-               {\r
-                       chomp($line);\r
-                       if ($line ne '') {\r
-                               my @temp = split(/\,/,$line);\r
-                               if ($cgiparams{'NAME'} eq $temp[1] && $cgiparams{'KEY'} ne $temp[0]) {\r
-                                       $errormessage=$Lang::tr{'duplicate name'};\r
-                                       return;\r
-                               }\r
-                               $key=$temp[0];\r
-                       }\r
-               }\r
-               unless($errormessage){\r
-                       my $fname = "${General::swroot}/firewall/defaultservices";\r
-                       my $prev = "";\r
-                       my $newline="";\r
-                       \r
-                       open(FILE, "$fname") or die 'Unable to open default services file.';\r
-                       my @current = <FILE>;\r
-                       close(FILE);\r
-                       \r
-                       foreach my $line (sort @current)\r
-                       {\r
-                               my @temp = split(/\,/,$line);\r
-                               if ($cgiparams{'NAME'} eq $temp[0]) {\r
-                                       $errormessage=$Lang::tr{'duplicate name'};\r
-                                       return;\r
-                               }\r
-                       }\r
-               }\r
-       }\r
-}\r
-\r
-sub get_icmptypes\r
-{\r
-       my $fname = "${General::swroot}/firewall/icmptypes";\r
-       my $newline="";\r
-       my @newarray=();\r
-       \r
-       open(FILE, "$fname") or die 'Unable to open icmp file.';\r
-       my @current = <FILE>;\r
-       close(FILE);\r
-\r
-       foreach $newline (sort @current)\r
-       {\r
-               chomp ($newline);\r
-               if (substr($newline, 0, 1) ne "#") {\r
-                       push (@newarray, $newline);\r
-               }\r
-       }\r
-       return (@newarray);\r
-}\r
-\r
+#!/usr/bin/perl
+#
+# This file is part of the IPCop Firewall.
+#
+# IPCop is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# IPCop is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with IPCop; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+#
+# Copyright (C) 2003-09-22 Darren Critchley <darrenc@telus.net>
+#
+# $Id: services.cgi,v 1.2.2.3 2005/04/29 23:37:07 franck78 Exp $
+#
+
+use strict;
+
+require 'CONFIG_ROOT/general-functions.pl';
+require "${General::swroot}/lang.pl";
+require "${General::swroot}/header.pl";
+
+my @icmptypes = &get_icmptypes();
+
+&Header::showhttpheaders();
+
+my %cgiparams=();
+my %selected=();
+my %checked=();
+my $filename = "${General::swroot}/firewall/customservices";
+my $key = 0; # used for finding last sequence number used 
+
+# Darren Critchley - vars for setting up sort order
+my $sort_col = '1';
+my $sort_type = 'a';
+my $sort_dir = 'asc';
+
+if ($ENV{'QUERY_STRING'} ne '') {
+       my ($item1, $item2, $item3) = split(/\&/,$ENV{'QUERY_STRING'});
+       if ($item1 ne '') {
+               ($junk, $sort_col) = split(/\=/,$item1)
+       }
+       if ($item2 ne '') {
+               ($junk, $sort_type) = split(/\=/,$item2)
+       }
+       if ($item3 ne '') {
+               ($junk, $sort_dir) = split(/\=/,$item3)
+       }
+}
+
+$cgiparams{'KEY'} = '';
+$cgiparams{'PORTS'} = '';
+$cgiparams{'PROTOCOL'} = '6';
+$cgiparams{'NAME'} = '';
+$cgiparams{'PORT_INVERT'} = 'off';
+$cgiparams{'PROTOCOL_INVERT'} = 'off';
+$cgiparams{'ICMP'} = 'BLANK';
+
+&Header::getcgihash(\%cgiparams);
+
+if ($cgiparams{'ACTION'} eq $Lang::tr{'add'}){
+
+       &validateparams();
+       unless($errormessage){
+               $key++; # Add one to last sequence number
+               open(FILE,">>$filename") or die 'Unable to open config file.';
+               flock FILE, 2;
+               print FILE "$key,$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";
+               close(FILE);
+               &General::log("$Lang::tr{'service added'}: $cgiparams{'NAME'}");
+               undef %cgiparams;
+       }
+}
+
+if ($cgiparams{'ACTION'} eq $Lang::tr{'update'})
+{
+       &validateparams();
+       # Darren Critchley - If there is an error don't waste any more processing time
+       if ($errormessage) { $cgiparams{'ACTION'} = $Lang::tr{'edit'}; goto UPD_ERROR; }
+
+       unless($errormessage){
+               open(FILE, $filename) or die 'Unable to open custom services file.';
+               my @current = <FILE>;
+               close(FILE);
+               my $line;
+               open(FILE, ">$filename") or die 'Unable to open config file.';
+               flock FILE, 2;
+               foreach $line (@current) {
+                       chomp($line);
+                       my @temp = split(/\,/,$line);
+                       if ($cgiparams{'KEY'} eq $temp[0]) {
+                               print FILE "$cgiparams{'KEY'},$cgiparams{'NAME'},$cgiparams{'PORTS'},$cgiparams{'PROTOCOL'},$cgiparams{'PORT_INVERT'},$cgiparams{'PROTOCOL_INVERT'},$cgiparams{'ICMP'}\n";
+                       } else {
+                               print FILE "$line\n";
+                       }
+               }
+               close(FILE);
+               &General::log("$Lang::tr{'service updated'}: $cgiparams{'NAME'}");
+               undef %cgiparams;
+       }
+UPD_ERROR:
+}
+
+if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'})
+{
+       open(FILE, "$filename") or die 'Unable to open custom services file.';
+       my @current = <FILE>;
+       close(FILE);
+
+       unless ($errormessage)
+       {
+               foreach my $line (@current)
+               {
+                       chomp($line);
+                       my @temp = split(/\,/,$line);
+                       if ($cgiparams{'KEY'} eq $temp[0]) {
+                               $cgiparams{'NAME'} = $temp[1];
+                               $cgiparams{'PORTS'} = $temp[2];
+                               $cgiparams{'PROTOCOL'} = $temp[3];
+                               $cgiparams{'PORT_INVERT'} = $temp[4];
+                               $cgiparams{'PROTOCOL_INVERT'} = $temp[5];
+                               $cgiparams{'ICMP'} = $temp[6];
+                       }
+                       
+               }
+       }
+}
+
+if ($cgiparams{'ACTION'} eq $Lang::tr{'remove'})
+{
+       open(FILE, $filename) or die 'Unable to open custom services file.';
+       my @current = <FILE>;
+       close(FILE);
+
+       open(FILE, ">$filename") or die 'Unable to open custom services file.';
+       flock FILE, 2;
+       foreach my $line (@current)
+       {
+               chomp($line);
+               if ($line ne '') {              
+                       my @temp = split(/\,/,$line);
+                       if ($cgiparams{'KEY'} eq $temp[0]) {
+                               &General::log("$Lang::tr{'service removed'}: $temp[1]");
+                       } else {
+                                       print FILE "$temp[0],$temp[1],$temp[2],$temp[3],$temp[4],$temp[5],$temp[6]\n";
+                       }
+               }
+       }
+       close(FILE);
+       undef %cgiparams;
+}
+
+if ($cgiparams{'ACTION'} eq $Lang::tr{'reset'})
+{
+       undef %cgiparams;
+}
+
+if ($cgiparams{'ACTION'} eq '')
+{
+       $cgiparams{'KEY'} = '';
+       $cgiparams{'PORTS'} = '';
+       $cgiparams{'PROTOCOL'} = '6';
+    $cgiparams{'NAME'} = '';
+       $cgiparams{'PORT_INVERT'} = 'off';
+       $cgiparams{'PROTOCOL_INVERT'} = 'off';
+       $cgiparams{'ICMP'} = 'BLANK';
+}
+
+# Darren Critchley - Bring in the protocols file built from /etc/protocols into hash %protocol
+require "${General::swroot}/firewall/protocols.pl";
+
+# Darren Critchley - figure out which protocol is selected
+$selected{'PROTOCOL'}{'tcpudp'}= '';
+$selected{'PROTOCOL'}{'all'}= '';
+foreach $line (keys %protocols) {
+#      $selected{'PROTOCOL'}{"$protocols{$line}"}= '';
+       $selected{'PROTOCOL'}{$line}= '';
+}
+$selected{'PROTOCOL'}{$cgiparams{'PROTOCOL'}} = 'SELECTED';
+
+# Darren Critchley - figure out which icmptype is selected
+$selected{'ICMP'}{$cgiparams{'ICMP'}} = 'SELECTED';
+
+$checked{'PORT_INVERT'}{'off'} = '';
+$checked{'PORT_INVERT'}{'on'} = '';
+$checked{'PORT_INVERT'}{$cgiparams{'PORT_INVERT'}} = 'CHECKED';
+$checked{'PROTOCOL_INVERT'}{'off'} = '';
+$checked{'PROTOCOL_INVERT'}{'on'} = '';
+$checked{'PROTOCOL_INVERT'}{$cgiparams{'PROTOCOL_INVERT'}} = 'CHECKED';
+
+&Header::openpage($Lang::tr{'services settings'}, 1, '');
+
+&Header::openbigbox('100%', 'LEFT', '', $errormessage);
+
+# DEBUG DEBUG
+#&Header::openbox('100%', 'LEFT', 'DEBUG');
+#foreach $line (keys %cgiparams) {
+#      print "<CLASS NAME='base'>$line = $cgiparams{$line}<BR>";
+#}
+#print "$sort_col\n";
+#print "$ENV{'QUERY_STRING'}\n";
+#print "&nbsp;</CLASS>\n";
+#&Header::closebox();
+
+if ($errormessage) {
+       &Header::openbox('100%', 'LEFT', $Lang::tr{'error messages'});
+       print "<CLASS NAME='base'><FONT COLOR='${Header::colourred}'>$errormessage\n</FONT>";
+       print "&nbsp;</CLASS>\n";
+       &Header::closebox();
+}
+
+if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){
+       &Header::openbox('100%', 'LEFT', "$Lang::tr{'edit service'}:");
+} else {
+       &Header::openbox('100%', 'LEFT', "$Lang::tr{'add service'}:");
+}
+# Darren Critchley - Show protocols with TCP, UDP, etc at the top of the list.
+print <<END
+<FORM METHOD='POST'>
+<DIV ALIGN='CENTER'>
+<TABLE WIDTH='100%' ALIGN='CENTER'>
+<TR align="center">
+       <TD><strong>$Lang::tr{'servicename'}</strong></TD>
+       <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>
+       <TD><strong>$Lang::tr{'ports'}</strong></TD>
+       <TD ALIGN='RIGHT'><strong>$Lang::tr{'invert'}</strong></TD>
+       <TD><strong>$Lang::tr{'protocol'}</strong></TD>
+       <TD>&nbsp;</TD>
+       <TD>&nbsp;</TD>
+</TR>
+<TR align="center">
+       <TD>
+               <INPUT TYPE='TEXT' NAME='NAME' VALUE='$cgiparams{'NAME'}' SIZE='20' MAXLENGTH='20'>
+       </TD>
+       <TD ALIGN='RIGHT'>
+               <INPUT TYPE='CHECKBOX' NAME='PORT_INVERT' $checked{'PORT_INVERT'}{'on'}>
+       </TD>
+       <TD>
+               <INPUT TYPE='TEXT' NAME='PORTS' VALUE='$cgiparams{'PORTS'}' SIZE='15' MAXLENGTH='11'>
+       </TD>
+       <TD ALIGN='RIGHT'>
+               <INPUT TYPE='CHECKBOX' NAME='PROTOCOL_INVERT' $checked{'PROTOCOL_INVERT'}{'on'}>
+       </TD>
+    <TD ALIGN='LEFT'>
+               <SELECT NAME='PROTOCOL'>
+                       <OPTION VALUE='tcp' $selected{'PROTOCOL'}{'tcp'}>TCP</OPTION>
+                       <OPTION VALUE='udp' $selected{'PROTOCOL'}{'udp'}>UDP</OPTION>
+                       <OPTION VALUE='tcpudp' $selected{'PROTOCOL'}{'tcpudp'}>TCP & UDP</OPTION>
+                       <OPTION VALUE='all' $selected{'PROTOCOL'}{'all'}>ALL</OPTION>
+                       <OPTION VALUE='icmp' $selected{'PROTOCOL'}{'icmp'}>ICMP</OPTION>
+                       <OPTION VALUE='gre' $selected{'PROTOCOL'}{'gre'}>GRE</OPTION>
+END
+;
+foreach $line (sort keys %protocols) {
+       # Darren Critchley - do not have duplicates in the list
+       if ($protocols{$line} ne '6' && $protocols{$line} ne '17' && $protocols{$line} ne '1' && $protocols{$line} ne '47'){
+#              print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$protocols{$line}}>".uc($line)."</OPTION>\n";
+               print "<OPTION VALUE='$line' $selected{'PROTOCOL'}{$line}>".uc($line)."</OPTION>\n";
+       }
+}
+print <<END
+               </SELECT>
+       </TD>
+</TR>
+<TR>
+       <TD>&nbsp;</TD>
+       <TD>&nbsp;</TD>
+       <TD>&nbsp;</TD>
+       <TD><strong>$Lang::tr{'icmp type'}:</strong></TD>
+       <TD ALIGN='LEFT'>
+                       <SELECT NAME='ICMP'>
+                               <OPTION VALUE='BLANK' $selected{'ICMP'}{'BLANK'}>Valid ICMP Types</OPTION>
+END
+;
+foreach $line (@icmptypes) {
+       if ($cgiparams{'ICMP'} eq $line){
+               print "<OPTION VALUE='$line' SELECTED>$line</OPTION>\n";
+       } else {
+               print "<OPTION VALUE='$line' >$line</OPTION>\n";
+       }
+}
+print <<END
+                       </SELECT>
+       </TD>
+</TR>
+<TR>
+END
+;
+if ($cgiparams{'ACTION'} eq $Lang::tr{'edit'}){
+       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'update'}'></TD>\n";
+       print "<INPUT TYPE='HIDDEN' NAME='KEY' VALUE='$cgiparams{'KEY'}'>\n";
+       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";
+} else {
+       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'add'}'></TD>\n";
+       print "<TD ALIGN='CENTER'><INPUT TYPE='SUBMIT' NAME='ACTION' VALUE='$Lang::tr{'reset'}'></TD>\n";
+}
+print <<END
+</TR>
+</TABLE>
+</DIV>
+</FORM>
+END
+;
+
+&Header::closebox();
+
+&Header::openbox('100%', 'LEFT', "$Lang::tr{'custom services'}:");
+print <<END
+<DIV ALIGN='CENTER'>
+<TABLE WIDTH='100%' ALIGN='CENTER'>
+<TR align="center">
+END
+;
+
+if ($sort_dir eq 'asc' && $sort_col eq '2') {
+       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=2&srtype=a&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'servicename'}</a></strong></TD>\n";
+} else {
+       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=2&srtype=a&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'servicename'}</a></strong></TD>\n";
+}
+if ($sort_dir eq 'asc' && $sort_col eq '3') {
+       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=3&srtype=n&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'ports'}</a></strong></TD>\n";
+} else {
+       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=3&srtype=n&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'ports'}</a></strong></TD>\n";
+}
+if ($sort_dir eq 'asc' && $sort_col eq '4') {
+       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=4&srtype=a&srtdir=dsc' title='$Lang::tr{'sort descending'}'>$Lang::tr{'protocol'}</a></strong></TD>\n";
+} else {
+       print "<TD WIDTH='25%'><strong><a href='services.cgi?sortcol=4&srtype=a&srtdir=asc' title='$Lang::tr{'sort ascending'}'>$Lang::tr{'protocol'}</a></strong></TD>\n";
+}
+
+print <<END
+       <TD WIDTH='25%'><strong>$Lang::tr{'icmp type'}</strong></TD>
+       <TD WIDTH='5%'>&nbsp;</TD>
+       <TD WIDTH='5%'>&nbsp;</TD>
+</TR>
+END
+;
+&display_custom_services();
+print <<END
+</TABLE>
+</DIV>
+END
+;
+&Header::closebox();
+
+&Header::openbox('100%', 'LEFT', "$Lang::tr{'default services'}:");
+print <<END
+<DIV ALIGN='CENTER'>
+<TABLE WIDTH='100%' ALIGN='CENTER'>
+<TR align="center">
+       <TD><strong>$Lang::tr{'servicename'}</strong></TD>
+       <TD><strong>$Lang::tr{'ports'}</strong></TD>
+       <TD><strong>$Lang::tr{'protocol'}</strong></TD>
+</TR>
+END
+;
+&display_default_services();
+print <<END
+</TABLE>
+</DIV>
+END
+;
+&Header::closebox();
+    print "$Lang::tr{'this feature has been sponsored by'} : ";
+    print "<A HREF='http://www.kdi.ca/' TARGET='_blank'>Kobelt Development Inc.</A>.\n";
+
+
+&Header::closebigbox();
+
+&Header::closepage();
+
+sub display_custom_services
+{
+       
+       open(FILE, "$filename") or die 'Unable to open services file.';
+       my @current = <FILE>;
+       close(FILE);
+
+       my $id = 0;
+       my $port_inv = '';
+       my $prot_inv = '';
+       my $port_inv_tail = '';
+       my $prot_inv_tail = '';
+       my @outarray = &General::srtarray($sort_col,$sort_type,$sort_dir,@current);
+       foreach $line (@outarray)
+       {
+               chomp($line);
+               if ($line ne ''){
+                       my @temp = split(/\,/,$line);
+                       # Darren Critchley highlight the row we are editing
+                       if ( $cgiparams{'ACTION'} eq $Lang::tr{'edit'} && $cgiparams{'KEY'} eq $temp[0] ) { 
+                               print "<TR BGCOLOR='${Header::colouryellow}'>\n";
+                       } else {
+                               if ($id % 2) {
+                                       print "<TR BGCOLOR='${Header::table1colour}'>\n"; 
+                               } else {
+                       print "<TR BGCOLOR='${Header::table2colour}'>\n";
+                               }
+                       }
+                       print "<TD>$temp[1]</TD>\n";
+                       if ($temp[4] eq 'on'){$port_inv = " <strong><font color='RED'>! (</font></strong>";$port_inv_tail = "<strong><font color='RED'>)</font></strong>";}else{$port_inv='';$port_inv_tail='';}
+                       print "<TD ALIGN='CENTER'>" . $port_inv . &cleanport("$temp[2]") . $port_inv_tail . "</TD>\n";
+                       if ($temp[5] eq 'on'){$prot_inv = " <strong><font color='RED'>! (</font></strong>";$prot_inv_tail = "<strong><font color='RED'>)</font></strong>";}else{$prot_inv='';$prot_inv_tail='';}
+                       print "<TD ALIGN='CENTER'>" . $prot_inv . &cleanprotocol("$temp[3]") . $prot_inv_tail . "</TD>\n";
+                       if ($temp[6] eq 'BLANK') {
+                               print "<TD ALIGN='CENTER'>N/A</TD>\n";
+                       } else {
+                               print "<TD ALIGN='CENTER'>$temp[6]</TD>\n";
+                       }
+                       print <<END
+<FORM METHOD='POST' NAME='frm$temp[0]'>
+<TD ALIGN='CENTER'>
+       <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'edit'}'>
+       <INPUT TYPE='image' NAME='$Lang::tr{'edit'}' src='/images/edit.gif' alt='$Lang::tr{'edit'}' title='$Lang::tr{'edit'}' width='20' height='20' border='0'>
+       <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>
+</TD>
+</FORM>
+<FORM METHOD='POST' NAME='frm$temp[0]b'>
+<TD ALIGN='CENTER'>
+       <INPUT TYPE='hidden' NAME='ACTION' VALUE='$Lang::tr{'remove'}'>
+       <INPUT TYPE='image' NAME='$Lang::tr{'remove'}' src='/images/delete.gif' alt='$Lang::tr{'remove'}' title='$Lang::tr{'remove'}' width='20' height='20' border='0'>
+       <INPUT TYPE='hidden' NAME='KEY' VALUE='$temp[0]'>
+</TD>
+</FORM>
+END
+;
+                       print "</TR>\n";
+                       $id++;
+               }
+       }
+}
+
+sub display_default_services
+{
+       my $fname = "${General::swroot}/firewall/defaultservices";
+       my $prev = "";
+       my $newline="";
+       
+       open(FILE, "$fname") or die 'Unable to open default services file.';
+       my @current = <FILE>;
+       close(FILE);
+       
+       my $id = 0;
+       
+       foreach my $line (sort @current)
+       {
+               my @temp = split(/\,/,$line);
+               if ($id % 2) {
+                       print "<TR BGCOLOR='${Header::table1colour}'>\n"; 
+               } else {
+               print "<TR BGCOLOR='${Header::table2colour}'>\n";
+               }
+               print "<TD>$temp[0]</TD>\n";
+               print "<TD ALIGN='CENTER'>$temp[1]</TD>\n";
+               print "<TD ALIGN='CENTER'>" . &cleanprotocol("$temp[2]") . "</TD>\n";
+               print "</TR>\n";
+               $id++;
+       }
+}
+
+sub cleanprotocol
+{
+       my $prtcl = $_[0];
+       chomp($prtcl);
+       if ($prtcl eq 'tcpudp') {
+               $prtcl = 'TCP & UDP';
+       } else {
+               $prtcl = uc($prtcl);
+       }
+       return $prtcl;
+}
+
+sub cleanport
+{
+       my $prt = $_[0];
+       chomp($prt);
+       # Darren Critchley - Format the ports
+       $prt =~ s/-/ - /;
+       $prt =~ s/:/ - /;
+       return $prt;
+}
+
+# Validate Field Entries
+sub validateparams 
+{
+       $erromessage='';
+       if ($cgiparams{'PROTOCOL'} eq 'tcp' || $cgiparams{'PROTOCOL'} eq 'udp' || $cgiparams{'PROTOCOL'} eq 'tcpudp' || $cgiparams{'PROTOCOL'} eq 'all') {
+               # Darren Critchley - Get rid of dashes in port ranges
+               $cgiparams{'PORTS'}=~ tr/-/:/;
+               # Darren Critchley - code to substitue wildcards
+               if ($cgiparams{'PORTS'} eq "*") {
+                       $cgiparams{'PORTS'} = "1:65535";
+               }
+               if ($cgiparams{'PORTS'} =~ /^(\D)\:(\d+)$/) {
+                       $cgiparams{'PORTS'} = "1:$2";
+               }
+               if ($cgiparams{'PORTS'} =~ /^(\d+)\:(\D)$/) {
+                       $cgiparams{'PORTS'} = "$1:65535";
+               }
+               # Darren Critchley - watch the order here, the validportrange sets errormessage=''
+               $errormessage = &General::validportrange($cgiparams{'PORTS'}, 'src');
+               if ($errormessage) {return;}
+       } else {
+               $cgiparams{'PORTS'} = "";
+       }
+       if ($cgiparams{'PROTOCOL'} eq 'tcp') {
+               $cgiparams{'ICMP'} = "BLANK";
+       }
+       
+       if($cgiparams{'PORTS'} eq '' && $cgiparams{'PORT_INVERT'} ne 'off'){
+               $cgiparams{'PORT_INVERT'} = 'off';
+       }
+       if ($cgiparams{'NAME'} eq '') {
+               $errormessage = $Lang::tr{'noservicename'};
+               return;
+       }
+       if ($cgiparams{'PROTOCOL'} eq 'icmp' && $cgiparams{'ICMP'} eq 'BLANK'){
+               $errormessage = $Lang::tr{'icmp selected but no type'};
+               return;
+       }
+    unless($errormessage){
+               $cgiparams{'NAME'}=&Header::cleanhtml($cgiparams{'NAME'});
+               open(FILE, $filename) or die 'Unable to open custom services file.';
+               my @current = <FILE>;
+               close(FILE);
+               foreach my $line (@current)
+               {
+                       chomp($line);
+                       if ($line ne '') {
+                               my @temp = split(/\,/,$line);
+                               if ($cgiparams{'NAME'} eq $temp[1] && $cgiparams{'KEY'} ne $temp[0]) {
+                                       $errormessage=$Lang::tr{'duplicate name'};
+                                       return;
+                               }
+                               $key=$temp[0];
+                       }
+               }
+               unless($errormessage){
+                       my $fname = "${General::swroot}/firewall/defaultservices";
+                       my $prev = "";
+                       my $newline="";
+                       
+                       open(FILE, "$fname") or die 'Unable to open default services file.';
+                       my @current = <FILE>;
+                       close(FILE);
+                       
+                       foreach my $line (sort @current)
+                       {
+                               my @temp = split(/\,/,$line);
+                               if ($cgiparams{'NAME'} eq $temp[0]) {
+                                       $errormessage=$Lang::tr{'duplicate name'};
+                                       return;
+                               }
+                       }
+               }
+       }
+}
+
+sub get_icmptypes
+{
+       my $fname = "${General::swroot}/firewall/icmptypes";
+       my $newline="";
+       my @newarray=();
+       
+       open(FILE, "$fname") or die 'Unable to open icmp file.';
+       my @current = <FILE>;
+       close(FILE);
+
+       foreach $newline (sort @current)
+       {
+               chomp ($newline);
+               if (substr($newline, 0, 1) ne "#") {
+                       push (@newarray, $newline);
+               }
+       }
+       return (@newarray);
+}
+