@Stefan: There should be an exception in the UI that these rules can be created when REDIRECT is being used. > On 1 Jul 2021, at 16:04, Jon Murphy wrote: > >> You probably want “any” as destination. > > Those are the only choices that allow a Save. When I enter an IP address I get this error: > > > Error messages > > Source and destination IP addresses are from the same subnet. > > > > Jon > >> On Jul 1, 2021, at 3:08 AM, Michael Tremer wrote: >> >> Hey Jon, >> >> You probably want “any” as destination. >> >> -Michael >> >>> On 1 Jul 2021, at 04:08, Jon Murphy wrote: >>> >>> Hi Stefan, >>> >>> Thank you for taking this on! >>> >>> I applied the patchwork.ipfire patch. >>> >>> I think I entered something wrong since I cannot get things to work. I tried both with Destination Firewall GREEN & Firewall RED. >>> >>> >>> Does the Firewall Rule seem right? >>> >>> Best regards, >>> Jon >>> >>> >>> Here is the rule I set up: >>> >>> >>> >>> >>> >>> >>> >>> And this is what I see with conntrack: >>> >>> conntrack -E -e NEW,UPDATE | grep -e "=53 " >>> >>> [NEW] udp 17 30 src=192.168.1.102 dst=1.2.3.4 sport=51169 dport=53 [UNREPLIED] src=1.2.3.4 dst=10.7.4.10 sport=53 dport=51169 >>> [NEW] udp 17 30 src=192.168.1.102 dst=1.2.3.4 sport=54168 dport=53 [UNREPLIED] src=1.2.3.4 dst=10.7.4.10 sport=53 dport=54168 >>> [NEW] udp 17 30 src=192.168.1.102 dst=1.2.3.4 sport=56094 dport=53 [UNREPLIED] src=1.2.3.4 dst=10.7.4.10 sport=53 dport=56094 >>> [NEW] udp 17 30 src=192.168.1.102 dst=1.2.3.4 sport=52964 dport=53 [UNREPLIED] src=1.2.3.4 dst=10.7.4.10 sport=53 dport=52964 >>> [NEW] udp 17 30 src=192.168.1.102 dst=1.2.3.4 sport=53279 dport=53 [UNREPLIED] src=1.2.3.4 dst=10.7.4.10 sport=53 dport=53279 >>> [NEW] udp 17 30 src=192.168.1.102 dst=1.2.3.4 sport=61657 dport=53 [UNREPLIED] src=1.2.3.4 dst=10.7.4.10 sport=53 dport=61657 >>> [NEW] udp 17 30 src=192.168.1.102 dst=1.2.3.4 sport=57723 dport=53 [UNREPLIED] src=1.2.3.4 dst=10.7.4.10 sport=53 dport=57723 >>> >>> >>> >>> >>>> On Jun 30, 2021, at 2:14 PM, Stefan Schantl wrote: >>>> >>>> Hello Matthias, Hello Michael, Hello Jon, Hello *, >>>> >>>> I've followed the conversation on this list since the first mail and >>>> thoughts about forcing DNS traffic to use the local resolver. >>>> >>>> It was a very long journey and lot of time and work has been spent to >>>> get to the present point. >>>> >>>> As Michael requested here, I've digged through the lines of the perl >>>> script which is responsible for creating the firewall rules and >>>> surprisingly found that everyting which is needed to create generic >>>> REDIRECT rules already was written in the past - it just did not work >>>> as designed/expected. >>>> >>>> Finaly I was able to adjust these lines of code and to repair that >>>> feature. >>>> >>>> A redirect rule can be created by picking a single host or group of >>>> hosts or entire network(s) as source, selecting NAT (DNAT) and choosing >>>> the Firewall itself as target. >>>> >>>> The protocol or service or service group which should be redirected has >>>> to be selected afterwards. If you want to redirect a given port to >>>> another one it can be specified as "Target port". >>>> >>>> All created redirect rules are displayed as "input rules". >>>> >>>> >>>> The patch directly can be accessed here: >>>> >>>> https://patchwork.ipfire.org/project/ipfire/patch/20210630184031.7726-1-stefan.schantl(a)ipfire.org/ >>>> >>>> Best regards, >>>> >>>> -Stefan >>>> >>>>> Hello, >>>>> >>>>>> On 28 Jun 2021, at 18:53, Jon Murphy wrote: >>>>>> >>>>>> Hi Michael! Happy Monday! >>>>>> >>>>>> >>>>>>> Why do we not extend the firewall UI probably by about 20 lines >>>>>>> of code instead of adding many hundreds of lines? >>>>>>> >>>>>>> Please can someone elaborate on this more? >>>>>> >>>>>> Doing a DNS redirect, via the WegBUI, has been an issue since >>>>>> 2015. I found this quote in the old forum: >>>>>> >>>>>> "Having investigated a bit more I have concluded that it's not >>>>>> currently possible to create such rules through the WUI. >>>>>> >>>>>> There are a number of obstacles: >>>>>> 1. It is not allowed to create a rule where source IP and >>>>>> destination nat IP is on the same subnetwork (e.g. GREEN), WUI >>>>>> error message: "Source and destination IP addresses are from the >>>>>> same subnet." >>>>>> >>>>>> 2. WUI will not allow you to create a rule without a destination >>>>>> (the filtered packet must adhere to a destination, not only a port) >>>>>> and the destination MUST be an IP address of one of the IPFire >>>>>> interfaces, which limits whats possible a great deal." >>>>> >>>>> And these cannot be changed? >>>>> >>>>>> And I found this from 2016: >>>>>> https://bugzilla.ipfire.org/show_bug.cgi?id=11168 >>>>>> >>>>>> So I am guessing that no one has been able to determine a way to >>>>>> extend the WebGUI. >>>>> >>>>> Has anyone tried? I do not see any obvious reasons why this should >>>>> not be possible. >>>>> >>>>>> I am curious - Who created the >>>>>> https://ipfire:444/cgi-bin/firewall.cgi page? And could they help? >>>>> >>>>> -Michael >>>>> >>>>>> Jon >>>>>> >>>>>> >>>>>>> On Jun 28, 2021, at 11:04 AM, Michael Tremer < >>>>>>> michael.tremer(a)ipfire.org> wrote: >>>>>>> >>>>>>> Hello Matthias, >>>>>>> >>>>>>>> On 27 Jun 2021, at 14:48, Matthias Fischer < >>>>>>>> matthias.fischer(a)ipfire.org> wrote: >>>>>>>> >>>>>>>> From: Marcel Lorenz >>>>>>> >>>>>>> Thank you for sending this patch on Marcel’s behalf, but I would >>>>>>> much more prefer if he would submit his patches on his own. I do >>>>>>> not see why that isn’t possible. >>>>>>> >>>>>>>> Please note: >>>>>>>> This is a new addon written by Marcel Lorenz < >>>>>>>> marcel.lorenz(a)ipfire.org>. >>>>>>>> >>>>>>>> It adds a new GUI to IPFire for DNS/NTP *and* user specific >>>>>>>> port redirections. >>>>>>>> >>>>>>>> How its working: >>>>>>>> It has exactly the same functionalities as "Forcing >>>>>>>> DNS/NTP..." - and some more. >>>>>>>> >>>>>>>> By setting switches, DNS/NTP requests are automatically >>>>>>>> redirected to the local IPFire DNS/NTP servers. >>>>>>>> >>>>>>>> Additionally, the user can specify custom redirections. >>>>>>>> >>>>>>>> These rules are added to a new chain in PREROUTING => >>>>>>>> PORT_REDIRECT. >>>>>>>> >>>>>>>> To avoid problems with (e.g.) transparent 'squid' >>>>>>>> configurations, >>>>>>>> redirection rules are added automatically before existing >>>>>>>> 'squid' rules. >>>>>>> >>>>>>> This message does unfortunately not say why this add-on would be >>>>>>> useful. I am emphasising this again and again that it is not very >>>>>>> important how something is done specially. That should be >>>>>>> commented in the code and other implementation details should >>>>>>> also be documented there. >>>>>>> >>>>>>> As I have stated on this functionality many times before, I do >>>>>>> not see why this is necessary at all. >>>>>>> >>>>>>> Why is this an add-on? >>>>>>> >>>>>>> Why do we not extend the firewall UI probably by about 20 lines >>>>>>> of code instead of adding many hundreds of lines? >>>>>>> >>>>>>> Please can someone elaborate on this more? >>>>>>> >>>>>>> -Michael >>>>>>> >>>>>>>> Signed-off-by: Matthias Fischer >>>>>>>> --- >>>>>>>> config/portredir/EX-portredir.menu | 6 + >>>>>>>> config/portredir/lang/portredir.de.pl | 19 + >>>>>>>> config/portredir/lang/portredir.en.pl | 19 + >>>>>>>> config/portredir/portredir-backup | 1 + >>>>>>>> config/portredir/portredir.cgi | 525 >>>>>>>> ++++++++++++++++++++++++++ >>>>>>>> config/rootfiles/common/misc-progs | 1 + >>>>>>>> config/rootfiles/packages/portredir | 11 + >>>>>>>> lfs/portredir | 85 +++++ >>>>>>>> make.sh | 1 + >>>>>>>> src/initscripts/packages/portredir | 191 ++++++++++ >>>>>>>> src/misc-progs/Makefile | 2 +- >>>>>>>> src/misc-progs/portredirctrl.c | 47 +++ >>>>>>>> src/paks/portredir/install.sh | 32 ++ >>>>>>>> src/paks/portredir/uninstall.sh | 28 ++ >>>>>>>> src/paks/portredir/update.sh | 26 ++ >>>>>>>> 15 files changed, 993 insertions(+), 1 deletion(-) >>>>>>>> create mode 100644 config/portredir/EX-portredir.menu >>>>>>>> create mode 100644 config/portredir/lang/portredir.de.pl >>>>>>>> create mode 100644 config/portredir/lang/portredir.en.pl >>>>>>>> create mode 100644 config/portredir/portredir-backup >>>>>>>> create mode 100644 config/portredir/portredir.cgi >>>>>>>> create mode 100644 config/rootfiles/packages/portredir >>>>>>>> create mode 100644 lfs/portredir >>>>>>>> create mode 100644 src/initscripts/packages/portredir >>>>>>>> create mode 100644 src/misc-progs/portredirctrl.c >>>>>>>> create mode 100644 src/paks/portredir/install.sh >>>>>>>> create mode 100644 src/paks/portredir/uninstall.sh >>>>>>>> create mode 100644 src/paks/portredir/update.sh >>>>>>>> >>>>>>>> diff --git a/config/portredir/EX-portredir.menu >>>>>>>> b/config/portredir/EX-portredir.menu >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..8376e8053 >>>>>>>> --- /dev/null >>>>>>>> +++ b/config/portredir/EX-portredir.menu >>>>>>>> @@ -0,0 +1,6 @@ >>>>>>>> + $subfirewall->{'95.portredir'} = { >>>>>>>> + 'caption' => >>>>>>>> $Lang::tr{'portredir port redirections'}, >>>>>>>> + 'uri' => '/cgi- >>>>>>>> bin/portredir.cgi', >>>>>>>> + 'title' => >>>>>>>> "$Lang::tr{'portredir port redirections'}", >>>>>>>> + 'enabled' => 1 >>>>>>>> + }; >>>>>>>> diff --git a/config/portredir/lang/portredir.de.pl >>>>>>>> b/config/portredir/lang/portredir.de.pl >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..b932d4a85 >>>>>>>> --- /dev/null >>>>>>>> +++ b/config/portredir/lang/portredir.de.pl >>>>>>>> @@ -0,0 +1,19 @@ >>>>>>>> +%tr = ( >>>>>>>> +%tr, >>>>>>>> +'portredir enable addon' => 'Addon aktivieren', >>>>>>>> +'portredir common settings' => 'Allgemeine Einstellungen', >>>>>>>> +'portredir port redirections' => 'Portumleitungen', >>>>>>>> +'portredir fw for interface' => 'Firewalloptionen für das >>>>>>>> Interface', >>>>>>>> +'portredir enable user redirections' => 'Aktiviere >>>>>>>> benutzerdefinierte Portumleitungen', >>>>>>>> +'portredir force local dns' => 'Erzwinge lokale DNS-Server', >>>>>>>> +'portredir force local ntp' => 'Erzwinge lokale NTP-Server', >>>>>>>> +'portredir custom redirections' => 'Benutzerdefinierte >>>>>>>> Portumleitungen', >>>>>>>> +'portredir remove rule' => 'Entferne Regel', >>>>>>>> +'portredir add rule' => 'Hinzufügen', >>>>>>>> +'portredir no entries' => 'Keine Einträge vorhanden.', >>>>>>>> +'portredir invalid address' => 'Ungültige Host-Addresse.', >>>>>>>> +'portredir empty input' => 'Fehlende Angabe: Bitte geben Sie >>>>>>>> einen gültigen Host an.', >>>>>>>> +'portredir save to activate' => 'Speichern, um Änderungen zu >>>>>>>> aktivieren', >>>>>>>> +); >>>>>>>> + >>>>>>>> +#EOF >>>>>>>> diff --git a/config/portredir/lang/portredir.en.pl >>>>>>>> b/config/portredir/lang/portredir.en.pl >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..f442f3eaa >>>>>>>> --- /dev/null >>>>>>>> +++ b/config/portredir/lang/portredir.en.pl >>>>>>>> @@ -0,0 +1,19 @@ >>>>>>>> +%tr = ( >>>>>>>> +%tr, >>>>>>>> +'portredir enable addon' => 'Enable addon', >>>>>>>> +'portredir common settings' => 'Common settings', >>>>>>>> +'portredir port redirections' => 'Port redirections', >>>>>>>> +'portredir fw for interface' => 'Firewall options for >>>>>>>> interface', >>>>>>>> +'portredir enable user redirections' => 'Enable user port >>>>>>>> redirections', >>>>>>>> +'portredir force local dns' => 'Enforce local DNS servers', >>>>>>>> +'portredir force local ntp' => 'Enforce local NTP servers', >>>>>>>> +'portredir custom redirections' => 'Custom port redirections', >>>>>>>> +'portredir remove rule' => 'Remove rule', >>>>>>>> +'portredir add rule' => 'Add new', >>>>>>>> +'portredir no entries' => 'No entries at the moment.', >>>>>>>> +'portredir invalid address' => 'Invalid host address.', >>>>>>>> +'portredir empty input' => 'Empty input: Please enter a valid >>>>>>>> host.', >>>>>>>> +'portredir save to activate' => 'Save to activate changes', >>>>>>>> +); >>>>>>>> + >>>>>>>> +#EOF >>>>>>>> diff --git a/config/portredir/portredir-backup >>>>>>>> b/config/portredir/portredir-backup >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..bd2ada742 >>>>>>>> --- /dev/null >>>>>>>> +++ b/config/portredir/portredir-backup >>>>>>>> @@ -0,0 +1 @@ >>>>>>>> +/var/ipfire/portredir >>>>>>>> diff --git a/config/portredir/portredir.cgi >>>>>>>> b/config/portredir/portredir.cgi >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..4913dda3f >>>>>>>> --- /dev/null >>>>>>>> +++ b/config/portredir/portredir.cgi >>>>>>>> @@ -0,0 +1,525 @@ >>>>>>>> +#!/usr/bin/perl >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire.org - A linux based >>>>>>>> firewall # >>>>>>>> +# Copyright (C) 2021 IPFire Team >>>>>>>> # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# This program 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 3 of the >>>>>>>> License, or # >>>>>>>> +# (at your option) any later >>>>>>>> version. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# This program 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 this program. If not, see < >>>>>>>> http://www.gnu.org/licenses/>. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> + >>>>>>>> +use strict; >>>>>>>> + >>>>>>>> +# enable only the following on debugging purpose >>>>>>>> +use warnings; >>>>>>>> +use CGI::Carp 'fatalsToBrowser'; >>>>>>>> + >>>>>>>> +require '/var/ipfire/general-functions.pl'; >>>>>>>> +require "${General::swroot}/lang.pl"; >>>>>>>> +require "${General::swroot}/header.pl"; >>>>>>>> + >>>>>>>> +# File declarations >>>>>>>> +my $settingsfile = "${General::swroot}/portredir/settings"; >>>>>>>> +my $redirectsfile = "${General::swroot}/portredir/redirects"; >>>>>>>> + >>>>>>>> +# Create empty settingsfiles if they does not exist yet >>>>>>>> +unless (-e "$settingsfile") { system ("touch $settingsfile"); >>>>>>>> } >>>>>>>> +unless (-e "$redirectsfile") { system ("touch >>>>>>>> $redirectsfile"); } >>>>>>>> + >>>>>>>> +# load ipfire settings >>>>>>>> +our %netsettings = (); >>>>>>>> +our %color = (); >>>>>>>> +&General::readhash("${General::swroot}/ethernet/settings", >>>>>>>> \%netsettings); >>>>>>>> +&General::readhash("/srv/web/ipfire/html/themes/ipfire/include >>>>>>>> /colors.txt", \%color); >>>>>>>> + >>>>>>>> +my %settings=(); >>>>>>>> +my %portredirs=(); >>>>>>>> +my %checked=(); # Checkbox manipulations >>>>>>>> +my $errormessage=''; >>>>>>>> +my %selected=(); >>>>>>>> +our %redirects=(); >>>>>>>> + >>>>>>>> +$settings{'ACTION'} = ''; >>>>>>>> +$settings{'REDIR_ENABLE_ADDON'}="off"; >>>>>>>> +$settings{'REDIR_CUSTOM_GREEN'}="off"; >>>>>>>> +$settings{'REDIR_CUSTOM_BLUE'}="off"; >>>>>>>> +$settings{'REDIR_CUSTOM_ORANGE'}="off"; >>>>>>>> +$settings{'REDIR_DNS_GREEN'}="off"; >>>>>>>> +$settings{'REDIR_NTP_GREEN'}="off"; >>>>>>>> +$settings{'REDIR_DNS_BLUE'}="off"; >>>>>>>> +$settings{'REDIR_NTP_BLUE'}="off"; >>>>>>>> +$settings{'REDIR_DNS_ORANGE'}="off"; >>>>>>>> +$settings{'REDIR_NTP_ORANGE'}="off"; >>>>>>>> + >>>>>>>> +&Header::showhttpheaders(); >>>>>>>> + >>>>>>>> +# Get GUI values >>>>>>>> +&Header::getcgihash(\%settings); >>>>>>>> + >>>>>>>> +# Save action >>>>>>>> +if ($settings{'ACTION'} eq $Lang::tr{'save'}) { >>>>>>>> + >>>>>>>> + # If custom rules enabled, deactivate default rules on >>>>>>>> interface >>>>>>>> + if ($settings{'REDIR_CUSTOM_GREEN'} eq "on" ) { >>>>>>>> + $settings{'REDIR_DNS_GREEN'}="off"; >>>>>>>> + $settings{'REDIR_NTP_GREEN'}="off"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if ($settings{'REDIR_CUSTOM_BLUE'} eq "on" ) { >>>>>>>> + $settings{'REDIR_DNS_BLUE'}="off"; >>>>>>>> + $settings{'REDIR_NTP_BLUE'}="off"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + if ($settings{'REDIR_CUSTOM_ORANGE'} eq "on" ) { >>>>>>>> + $settings{'REDIR_DNS_ORANGE'}="off"; >>>>>>>> + $settings{'REDIR_NTP_ORANGE'}="off"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + &General::writehash($settingsfile, \%settings); >>>>>>>> + >>>>>>>> + if ($settings{'REDIR_ENABLE_ADDON'} eq "on") { >>>>>>>> + system ('/usr/local/bin/portredirctrl restart >>>>>>>>> /dev/null 2>&1'); >>>>>>>> + system ('/usr/local/bin/portredirctrl enable >>>>>>>>> /dev/null 2>&1'); >>>>>>>> + &General::log('portredir addon: port >>>>>>>> redirections enabled'); >>>>>>>> + } >>>>>>>> + if ($settings{'REDIR_ENABLE_ADDON'} eq "off") { >>>>>>>> + system ('/usr/local/bin/portredirctrl disable >>>>>>>>> /dev/null 2>&1'); >>>>>>>> + system ('/usr/local/bin/portredirctrl stop >>>>>>>>> /dev/null 2>&1'); >>>>>>>> + &General::log('portredir addon: port >>>>>>>> redirections disabled'); >>>>>>>> + } >>>>>>>> + >>>>>>>> +# Add/edit an entry to the redirectsfile. >>>>>>>> + >>>>>>>> +} elsif (($settings{'ACTION'} eq $Lang::tr{'add'}) || >>>>>>>> ($settings{'ACTION'} eq $Lang::tr{'update'})) { >>>>>>>> + >>>>>>>> + # Check if any input has been performed. >>>>>>>> + if ($settings{'REDIR_ENTRY_ADDRESS'} ne '') { >>>>>>>> + >>>>>>>> + # Check if the given input is no valid IP- >>>>>>>> address, display an error message. >>>>>>>> + if >>>>>>>> (!&General::validip($settings{'REDIR_ENTRY_ADDRESS'})) { >>>>>>>> + $errormessage = "$Lang::tr{'portredir >>>>>>>> invalid address'}"; >>>>>>>> + } >>>>>>>> + } else { >>>>>>>> + $errormessage = "$Lang::tr{'portredir empty >>>>>>>> input'}"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + # Go further if there was no error. >>>>>>>> + if ($errormessage eq '') { >>>>>>>> + my %redirects = (); >>>>>>>> + my $id; >>>>>>>> + my $status; >>>>>>>> + >>>>>>>> + # Assign hash values. >>>>>>>> + my $new_entry_interface = >>>>>>>> $settings{'REDIR_ENTRY_INTERFACE'}; >>>>>>>> + my $new_entry_protocol = >>>>>>>> $settings{'REDIR_ENTRY_PROTOCOL'}; >>>>>>>> + my $new_entry_port = >>>>>>>> $settings{'REDIR_ENTRY_PORT'}; >>>>>>>> + my $new_entry_address = >>>>>>>> $settings{'REDIR_ENTRY_ADDRESS'}; >>>>>>>> + my $new_entry_remark = >>>>>>>> $settings{'REDIR_ENTRY_REMARK'}; >>>>>>>> + >>>>>>>> + # Read-in redirectsfile. >>>>>>>> + &General::readhasharray($redirectsfile, >>>>>>>> \%redirects); >>>>>>>> + >>>>>>>> + # Check if we should edit an existing entry and >>>>>>>> got an ID. >>>>>>>> + if (($settings{'ACTION'} eq >>>>>>>> $Lang::tr{'update'}) && ($settings{'ID'})) { >>>>>>>> + # Assin the provided id. >>>>>>>> + $id = $settings{'ID'}; >>>>>>>> + >>>>>>>> + # Undef the given ID. >>>>>>>> + undef($settings{'ID'}); >>>>>>>> + >>>>>>>> + # Grab the configured status of the >>>>>>>> corresponding entry. >>>>>>>> + $status = $redirects{$id}[4]; >>>>>>>> + } else { >>>>>>>> + # Each newly added entry automatically >>>>>>>> should be enabled. >>>>>>>> + $status = "enabled"; >>>>>>>> + >>>>>>>> + # Generate the ID for the new entry. >>>>>>>> + # >>>>>>>> + # Sort the keys by their ID and store >>>>>>>> them in an array. >>>>>>>> + my @keys = sort { $a <=> $b } keys >>>>>>>> %redirects; >>>>>>>> + >>>>>>>> + # Reverse the key array. >>>>>>>> + my @reversed = reverse(@keys); >>>>>>>> + >>>>>>>> + # Obtain the last used id. >>>>>>>> + my $last_id = @reversed[0]; >>>>>>>> + >>>>>>>> + # Increase the last id by one and use >>>>>>>> it as id for the new entry. >>>>>>>> + $id = ++$last_id; >>>>>>>> + } >>>>>>>> + >>>>>>>> + # Add/Modify the entry to/in the redirects >>>>>>>> hash. >>>>>>>> + $redirects{$id} = ["$new_entry_interface", >>>>>>>> "$new_entry_protocol", "$new_entry_port", >>>>>>>> "$new_entry_address","$status", "$new_entry_remark"]; >>>>>>>> + >>>>>>>> + # Write the changed redirects hash to the >>>>>>>> redirects file. >>>>>>>> + &General::writehasharray($redirectsfile, >>>>>>>> \%redirects); >>>>>>>> + } >>>>>>>> + >>>>>>>> +# Toggle Enabled/Disabled for an existing entry on the >>>>>>>> redirects list. >>>>>>>> + >>>>>>>> +} elsif ($settings{'ACTION'} eq $Lang::tr{'toggle enable >>>>>>>> disable'}) { >>>>>>>> + my %redirects = (); >>>>>>>> + >>>>>>>> + # Only go further, if an ID has been passed. >>>>>>>> + if ($settings{'ID'}) { >>>>>>>> + # Assign the given ID. >>>>>>>> + my $id = $settings{'ID'}; >>>>>>>> + >>>>>>>> + # Undef the given ID. >>>>>>>> + undef($settings{'ID'}); >>>>>>>> + >>>>>>>> + # Read-in ignoredfile. >>>>>>>> + &General::readhasharray($redirectsfile, >>>>>>>> \%redirects); >>>>>>>> + >>>>>>>> + # Grab the configured status of the >>>>>>>> corresponding entry. >>>>>>>> + my $status = $redirects{$id}[4]; >>>>>>>> + >>>>>>>> + # Switch the status. >>>>>>>> + if ($status eq "disabled") { >>>>>>>> + $status = "enabled"; >>>>>>>> + } else { >>>>>>>> + $status = "disabled"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + # Modify the status of the existing entry. >>>>>>>> + $redirects{$id} = ["$redirects{$id}[0]", >>>>>>>> "$redirects{$id}[1]", "$redirects{$id}[2]", >>>>>>>> "$redirects{$id}[3]","$status", "$redirects{$id}[5]"]; >>>>>>>> + >>>>>>>> + # Write the changed ignored hash to the >>>>>>>> redirects file. >>>>>>>> + &General::writehasharray($redirectsfile, >>>>>>>> \%redirects); >>>>>>>> + } >>>>>>>> + >>>>>>>> +# Remove entry from redirects list. >>>>>>>> + >>>>>>>> +} elsif ($settings{'ACTION'} eq $Lang::tr{'remove'}) { >>>>>>>> + my %redirects = (); >>>>>>>> + >>>>>>>> + # Read-in redirectsfile. >>>>>>>> + &General::readhasharray($redirectsfile, \%redirects); >>>>>>>> + >>>>>>>> + # move data on key up >>>>>>>> + foreach my $key (sort keys %redirects) { >>>>>>>> + if ($key >= $settings{'ID'}) { >>>>>>>> + my $next = $key + 1; >>>>>>>> + if (exists $redirects{$next}) { >>>>>>>> + foreach my $i (0 .. >>>>>>>> $#{$redirects{$next}}) { $redirects{$key}[$i] = >>>>>>>> $redirects{$next}[$i]; } >>>>>>>> + } >>>>>>>> + } >>>>>>>> + } >>>>>>>> + >>>>>>>> + my $last_key = (sort {$a <=> $b} keys %redirects)[-1]; >>>>>>>> + delete $redirects{$last_key}; >>>>>>>> + >>>>>>>> + # Undef the given ID. >>>>>>>> + undef($settings{'ID'}); >>>>>>>> + >>>>>>>> + # Write the changed redirects hash to file. >>>>>>>> + &General::writehasharray($redirectsfile, \%redirects); >>>>>>>> +} >>>>>>>> + >>>>>>>> +# Load settings from file >>>>>>>> +&General::readhash($settingsfile, \%settings); >>>>>>>> +&General::readhasharray($redirectsfile, \%redirects); >>>>>>>> + >>>>>>>> +# Call functions to generate whole page. >>>>>>>> +&Header::openpage($Lang::tr{'portredir port redirections'}, 1, >>>>>>>> ''); >>>>>>>> +&Header::openbigbox('100%', 'left', '', $errormessage); >>>>>>>> + >>>>>>>> +if ($errormessage) { >>>>>>>> + &Header::openbox('100%', 'left', $Lang::tr{'warning >>>>>>>> messages'}); >>>>>>>> + print "$errormessage "; >>>>>>>> + &Header::closebox(); >>>>>>>> +} >>>>>>>> + >>>>>>>> +$checked{'REDIR_ENABLE_ADDON'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_ENABLE_ADDON'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_ENABLE_ADDON'}{$settings{'REDIR_ENABLE_ADDON'} >>>>>>>> } = "checked='checked'"; >>>>>>>> +$checked{'REDIR_CUSTOM_GREEN'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_CUSTOM_GREEN'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_CUSTOM_GREEN'}{$settings{'REDIR_CUSTOM_GREEN'} >>>>>>>> } = "checked='checked'"; >>>>>>>> +$checked{'REDIR_CUSTOM_BLUE'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_CUSTOM_BLUE'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_CUSTOM_BLUE'}{$settings{'REDIR_CUSTOM_BLUE'}} >>>>>>>> = "checked='checked'"; >>>>>>>> +$checked{'REDIR_CUSTOM_ORANGE'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_CUSTOM_ORANGE'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_CUSTOM_ORANGE'}{$settings{'REDIR_CUSTOM_ORANGE >>>>>>>> '}} = "checked='checked'"; >>>>>>>> +$checked{'REDIR_DNS_GREEN'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_DNS_GREEN'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_DNS_GREEN'}{$settings{'REDIR_DNS_GREEN'}} = >>>>>>>> "checked='checked'"; >>>>>>>> +$checked{'REDIR_NTP_GREEN'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_NTP_GREEN'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_NTP_GREEN'}{$settings{'REDIR_NTP_GREEN'}} = >>>>>>>> "checked='checked'"; >>>>>>>> +$checked{'REDIR_DNS_BLUE'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_DNS_BLUE'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_DNS_BLUE'}{$settings{'REDIR_DNS_BLUE'}} = >>>>>>>> "checked='checked'"; >>>>>>>> +$checked{'REDIR_NTP_BLUE'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_NTP_BLUE'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_NTP_BLUE'}{$settings{'REDIR_NTP_BLUE'}} = >>>>>>>> "checked='checked'"; >>>>>>>> +$checked{'REDIR_DNS_ORANGE'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_DNS_ORANGE'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_DNS_ORANGE'}{$settings{'REDIR_DNS_ORANGE'}} = >>>>>>>> "checked='checked'"; >>>>>>>> +$checked{'REDIR_NTP_ORANGE'}{'off'} = ''; >>>>>>>> +$checked{'REDIR_NTP_ORANGE'}{'on'} = ''; >>>>>>>> +$checked{'REDIR_NTP_ORANGE'}{$settings{'REDIR_NTP_ORANGE'}} = >>>>>>>> "checked='checked'"; >>>>>>>> + >>>>>>>> +$selected{'REDIR_ENTRY_INTERFACE'}{$settings{'REDIR_ENTRY_INTE >>>>>>>> RFACE'}} = 'selected'; >>>>>>>> +$selected{'REDIR_ENTRY_PROTOCOL'}{$settings{'REDIR_ENTRY_PROTO >>>>>>>> COL'}} = 'selected'; >>>>>>>> + >>>>>>>> +&showMainBox(); >>>>>>>> +&showRedirectsBox(); >>>>>>>> + >>>>>>>> +&Header::closebigbox(); >>>>>>>> +&Header::closepage(); >>>>>>>> + >>>>>>>> +# Function to show main settings and options. >>>>>>>> +sub showMainBox() { >>>>>>>> + >>>>>>>> + &Header::openbox('100%', 'center', >>>>>>>> "$Lang::tr{'settings'}"); >>>>>>>> + print "
>>>>>>> action='$ENV{'SCRIPT_NAME'}'>"; >>>>>>>> + >>>>>>>> +print <>>>>>>> + >>>>>>>> + >>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> +END >>>>>>>> + >>>>>>>> + # create html table with header line 1 >>>>>>>> + print "
>>>>>>> bgcolor='$color{'color20'}'>$Lang::tr{'portredir common >>>>>>>> settings'}
>>>>>>> class='base'>$Lang::tr{'portredir enable addon'}:>>>>>>> name='REDIR_ENABLE_ADDON' $checked{'REDIR_ENABLE_ADDON'}{'on'} >>>>>>>> />
 
>>>>>>> border='0'>"; >>>>>>>> + print ""; >>>>>>>> + if ($netsettings{'GREEN_DEV'}) {print ""; >>>>>>>> + } else { print ""; } >>>>>>>> + if ($netsettings{'BLUE_DEV'}) {print ""; >>>>>>>> + } else { print ""; } >>>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print ""; >>>>>>>> + } else { print ""; } >>>>>>>> + >>>>>>>> + # the empty right row >>>>>>>> + print ""; >>>>>>>> + >>>>>>>> + # line 2 >>>>>>>> + print ""; >>>>>>>> + if ($netsettings{'GREEN_DEV'}) {print "";} else { print >>>>>>>> "";} >>>>>>>> + if ($netsettings{'BLUE_DEV'}) {print "";} >>>>>>>> else { print "";} >>>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print "";} else { print >>>>>>>> "";} >>>>>>>> + >>>>>>>> + # line 3 >>>>>>>> + print ""; >>>>>>>> + if ($netsettings{'GREEN_DEV'}) {print "";} else { print >>>>>>>> "";} >>>>>>>> + if ($netsettings{'BLUE_DEV'}) {print "";} >>>>>>>> else { print "";} >>>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print "";} else { print >>>>>>>> "";} >>>>>>>> + >>>>>>>> + # line 4 >>>>>>>> + print ""; >>>>>>>> + if ($netsettings{'GREEN_DEV'}) {print "";} else { print >>>>>>>> "";} >>>>>>>> + if ($netsettings{'BLUE_DEV'}) {print "";} else { print >>>>>>>> "";} >>>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print "";} else { print >>>>>>>> "";} >>>>>>>> + >>>>>>>> + print <>>>>>>> +
>>>>>>> align='left'>$Lang::tr{'portredir fw for interface'}>>>>>>> class='base' width='10%'>>>>>>>> color=green>$Lang::tr{'green'}>>>>>>> class='base' width='10%'>>>>>>>> class='base' width='10%'>>>>>>>> color=blue>$Lang::tr{'blue'}>>>>>>> class='base' width='10%'>>>>>>>> class='base' width='10%'>>>>>>>> color=orange>$Lang::tr{'orange'}>>>>>>> class='base' width='10%'>>>>>>>> width='30%'>
$Lang::tr{'portredir force local >>>>>>>> dns'}>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_DNS_GREEN' >>>>>>>> $checked{'REDIR_DNS_GREEN'}{'on'}>>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_DNS_BLUE' $checked{'REDIR_DNS_BLUE'}{'on'}>>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_DNS_ORANGE' >>>>>>>> $checked{'REDIR_DNS_ORANGE'}{'on'}>
$Lang::tr{'portredir force local >>>>>>>> ntp'}>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_NTP_GREEN' >>>>>>>> $checked{'REDIR_NTP_GREEN'}{'on'}>>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_NTP_BLUE' $checked{'REDIR_NTP_BLUE'}{'on'}>>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_NTP_ORANGE' >>>>>>>> $checked{'REDIR_NTP_ORANGE'}{'on'}>
$Lang::tr{'portredir enable user >>>>>>>> redirections'}>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_CUSTOM_GREEN' >>>>>>>> $checked{'REDIR_CUSTOM_GREEN'}{'on'}>>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_CUSTOM_BLUE' >>>>>>>> $checked{'REDIR_CUSTOM_BLUE'}{'on'}>>>>>>>> class='base' align='center'>>>>>>>> name='REDIR_CUSTOM_ORANGE' >>>>>>>> $checked{'REDIR_CUSTOM_ORANGE'}{'on'}>
>>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> +
 
$Lang::tr{'portredir >>>>>>>> save to activate'}>>>>>>> type='submit' name='ACTION' value=' $Lang::tr{'save'} >>>>>>>> '>
>>>>>>>> +END >>>>>>>> + >>>>>>>> +&Header::closebox(); >>>>>>>> +} >>>>>>>> + >>>>>>>> +# Function to show elements of the redirects file and allow to >>>>>>>> add or remove single members of it. >>>>>>>> +sub showRedirectsBox() { >>>>>>>> + &Header::openbox('100%', 'center', >>>>>>>> "$Lang::tr{'portredir custom redirections'}"); >>>>>>>> + >>>>>>>> + print <>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> +END >>>>>>>> + # Check if some rules have been added >>>>>>>> to be redirects. >>>>>>>> + if (keys (%redirects)) { >>>>>>>> + my $col = ""; >>>>>>>> + >>>>>>>> + # List all entries of the hash. >>>>>>>> + foreach my $key (sort keys >>>>>>>> %redirects){ >>>>>>>> + >>>>>>>> + # Assign data array >>>>>>>> positions to some nice variable names. >>>>>>>> + my $interface = >>>>>>>> $redirects{$key}[0]; >>>>>>>> + my $protocol = >>>>>>>> $redirects{$key}[1]; >>>>>>>> + my $port = >>>>>>>> $redirects{$key}[2]; >>>>>>>> + my $address = >>>>>>>> $redirects{$key}[3]; >>>>>>>> + my $status = >>>>>>>> $redirects{$key}[4]; >>>>>>>> + my $remark = >>>>>>>> $redirects{$key}[5]; >>>>>>>> + >>>>>>>> + # Check if the key (id) >>>>>>>> number is even or not. >>>>>>>> + if ($settings{'ID'} eq >>>>>>>> $key) { >>>>>>>> + $col="bgcolor=' >>>>>>>> ${Header::colouryellow}'"; >>>>>>>> + } elsif ($key % 2) { >>>>>>>> + $col="bgcolor=' >>>>>>>> $color{'color22'}'"; >>>>>>>> + } else { >>>>>>>> + $col="bgcolor=' >>>>>>>> $color{'color20'}'"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + # Choose icon for the >>>>>>>> checkbox. >>>>>>>> + my $gif; >>>>>>>> + my $gdesc; >>>>>>>> + >>>>>>>> + # Check if the status >>>>>>>> is enabled and select the correct image and description. >>>>>>>> + if ($status eq >>>>>>>> 'enabled' ) { >>>>>>>> + $gif = >>>>>>>> 'on.gif'; >>>>>>>> + $gdesc = >>>>>>>> $Lang::tr{'click to disable'}; >>>>>>>> + } else { >>>>>>>> + $gif = >>>>>>>> 'off.gif'; >>>>>>>> + $gdesc = >>>>>>>> $Lang::tr{'click to enable'}; >>>>>>>> + } >>>>>>>> + >>>>>>>> + print <>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> +END >>>>>>>> + } >>>>>>>> + } else { >>>>>>>> + # Print notice that currently >>>>>>>> no ports are redirected. >>>>>>>> + print "\n"; >>>>>>>> + print "\n"; >>>>>>>> + print "\n"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + print "
>>>>>>> bgcolor='$color{'color20'}' >>>>>>>> align='center'>$Lang::tr{'interface'}>>>>>>> bgcolor='$color{'color20'}' >>>>>>>> align='center'>$Lang::tr{'protocol'}>>>>>>> bgcolor='$color{'color20'}' >>>>>>>> align='center'>$Lang::tr{'port'}>>>>>>> bgcolor='$color{'color20'}' align='center'>$Lang::tr{'ip >>>>>>>> address'}>>>>>>> bgcolor='$color{'color20'}' >>>>>>>> align='center'>$Lang::tr{'remark'}>>>>>>> bgcolor='$color{'color20'}'>
>>>>>>> class='base' align='center' $col>>>>>>>> color=$interface>$Lang::tr{$interface}>>>>>>> class='base' align='center' $col>$protocol>>>>>>> class='base' align='center' $col>$port>>>>>>> class='base' align='center' $col> $address>>>>>>> class='base' align='center' $col> $remark>>>>>>> align='center' $col> >>>>>>>> +
>>>>>>> method='post' action='$ENV{'SCRIPT_NAME'}'> >>>>>>>> + >>>>>>>> >>>>>>> enable disable'}' /> >>>>>>>> + >>>>>>>> >>>>>>> src='/images/$gif' alt='$gdesc' title='$gdesc' /> >>>>>>>> + >>>>>>>> >>>>>>>> +
>>>>>>>> +
>>>>>>> align='center' $col> >>>>>>>> +
>>>>>>> method='post' action='$ENV{'SCRIPT_NAME'}'> >>>>>>>> + >>>>>>>> >>>>>>> /> >>>>>>>> + >>>>>>>> >>>>>>> src='/images/edit.gif' alt='$Lang::tr{'edit'}' >>>>>>>> title='$Lang::tr{'edit'}' /> >>>>>>>> + >>>>>>>> >>>>>>>> +
>>>>>>>> +
>>>>>>> align='center' $col> >>>>>>>> +
>>>>>>> method='post' name='$key' action='$ENV{'SCRIPT_NAME'}'> >>>>>>>> + >>>>>>>> >>>>>>> src='/images/delete.gif' title='$Lang::tr{'remove'}' >>>>>>>> alt='$Lang::tr{'remove'}'> >>>>>>>> + >>>>>>>> >>>>>>>> + >>>>>>>> >>>>>>> value='$Lang::tr{'remove'}'> >>>>>>>> +
>>>>>>>> +
>>>>>>> colspan='2'>$Lang::tr{'portredir no entries'}
\n"; >>>>>>>> + >>>>>>>> + # Section to add new elements or edit existing ones. >>>>>>>> + print <>>>>>>> +
>>>>>>>> +
>>>>>>>> +
>>>>>>>> +
>>>>>>>> + >>>>>>>> +END >>>>>>>> + >>>>>>>> + # Assign correct headline and button text. >>>>>>>> + my $buttontext; >>>>>>>> + my $entry_interface; >>>>>>>> + my $entry_protocol; >>>>>>>> + my $entry_port; >>>>>>>> + my $entry_address; >>>>>>>> + my $entry_remark; >>>>>>>> + >>>>>>>> + # Check if an ID (key) has been given, in this case an >>>>>>>> existing entry should be edited. >>>>>>>> + if ($settings{'ID'} ne '') { >>>>>>>> + $buttontext = $Lang::tr{'update'}; >>>>>>>> + print "\n"; >>>>>>>> + >>>>>>>> + # Grab address and remark for the given key. >>>>>>>> + $entry_interface = >>>>>>>> $redirects{$settings{'ID'}}[0]; >>>>>>>> + $entry_protocol = >>>>>>>> $redirects{$settings{'ID'}}[1]; >>>>>>>> + $entry_port = $redirects{$settings{'ID'}}[2]; >>>>>>>> + $entry_address = >>>>>>>> $redirects{$settings{'ID'}}[3]; >>>>>>>> + $entry_remark = $redirects{$settings{'ID'}}[5]; >>>>>>>> + >>>>>>>> + } else { >>>>>>>> + $buttontext = $Lang::tr{'add'}; >>>>>>>> + print "\n"; >>>>>>>> + print "\n"; >>>>>>>> + } >>>>>>>> + >>>>>>>> + print <>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>> action='$ENV{'SCRIPT_NAME'}'> >>>>>>>> + >>>>>>> value='$settings{'ID'}'> >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> + >>>>>>>> +
>>>>>>> colspan='6'>$Lang::tr{'update'}
>>>>>>> colspan='11'>$Lang::tr{'dnsforward add a new >>>>>>>> entry'}
 
>>>>>>> bgcolor='$color{'color22'}'>>>>>>>> bgcolor='$color{'color22'}' >>>>>>>> align='left'>$Lang::tr{'interface'}>>>>>>> bgcolor='$color{'color22'}' >>>>>>>> align='left'>$Lang::tr{'protocol'}>>>>>>> bgcolor='$color{'color22'}' >>>>>>>> align='left'> $Lang::tr{'port'}>>>>>>> bgcolor='$color{'color22'}' align='left'> $Lang::tr{'ip >>>>>>>> address'}>>>>>>> bgcolor='$color{'color22'}' >>>>>>>> align='left'> $Lang::tr{'remark'}>>>>>>> bgcolor='$color{'color22'}'>>>>>>>> bgcolor='$color{'color22'}'>
>>>>>>> name='REDIR_ENTRY_PORT' value='$entry_port' >>>>>>>> size='4'>>>>>>>> name='REDIR_ENTRY_ADDRESS' value='$entry_address' >>>>>>>> size='14'>>>>>>>> name='REDIR_ENTRY_REMARK' value='$entry_remark' >>>>>>>> size='35'>>>>>>>> align='center'>
>>>>>>>> +
>>>>>>>> +END >>>>>>>> + &Header::closebox(); >>>>>>>> +} >>>>>>>> diff --git a/config/rootfiles/common/misc-progs >>>>>>>> b/config/rootfiles/common/misc-progs >>>>>>>> index d6594b3f8..fbad2af8b 100644 >>>>>>>> --- a/config/rootfiles/common/misc-progs >>>>>>>> +++ b/config/rootfiles/common/misc-progs >>>>>>>> @@ -17,6 +17,7 @@ usr/local/bin/logwatch >>>>>>>> #usr/local/bin/mpfirectrl >>>>>>>> usr/local/bin/openvpnctrl >>>>>>>> usr/local/bin/pakfire >>>>>>>> +#usr/local/bin/portredirctrl >>>>>>>> usr/local/bin/qosctrl >>>>>>>> usr/local/bin/rebuildhosts >>>>>>>> usr/local/bin/rebuildroutes >>>>>>>> diff --git a/config/rootfiles/packages/portredir >>>>>>>> b/config/rootfiles/packages/portredir >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..4b4ba8366 >>>>>>>> --- /dev/null >>>>>>>> +++ b/config/rootfiles/packages/portredir >>>>>>>> @@ -0,0 +1,11 @@ >>>>>>>> +etc/rc.d/init.d/portredir >>>>>>>> +etc/rc.d/rc0.d/K77portredir >>>>>>>> +etc/rc.d/rc3.d/S23portredir >>>>>>>> +etc/rc.d/rc6.d/K77portredir >>>>>>>> +srv/web/ipfire/cgi-bin/portredir.cgi >>>>>>>> +usr/local/bin/portredirctrl >>>>>>>> +var/ipfire/addon-lang/portredir.de.pl >>>>>>>> +var/ipfire/addon-lang/portredir.en.pl >>>>>>>> +var/ipfire/backup/addons/includes/portredir >>>>>>>> +var/ipfire/menu.d/EX-portredir.menu >>>>>>>> +var/ipfire/portredir >>>>>>>> diff --git a/lfs/portredir b/lfs/portredir >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..a4911f71f >>>>>>>> --- /dev/null >>>>>>>> +++ b/lfs/portredir >>>>>>>> @@ -0,0 +1,85 @@ >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire.org - A linux based >>>>>>>> firewall # >>>>>>>> +# Copyright (C) 2007-2021 IPFire Team >>>>>>>> # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# This program 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 3 of the >>>>>>>> License, or # >>>>>>>> +# (at your option) any later >>>>>>>> version. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# This program 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 this program. If not, see < >>>>>>>> http://www.gnu.org/licenses/>. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> + >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> +# Definitions >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> + >>>>>>>> +include Config >>>>>>>> + >>>>>>>> +VER = 1.0 >>>>>>>> + >>>>>>>> +THISAPP = portredir-$(VER) >>>>>>>> +DIR_APP = $(DIR_SRC)/$(THISAPP) >>>>>>>> +TARGET = $(DIR_INFO)/$(THISAPP) >>>>>>>> +PROG = portredir >>>>>>>> +PAK_VER = 1 >>>>>>>> + >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> +# Top-level Rules >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> + >>>>>>>> +install : $(TARGET) >>>>>>>> + >>>>>>>> +check : >>>>>>>> + >>>>>>>> +download : >>>>>>>> + >>>>>>>> +md5 : >>>>>>>> + >>>>>>>> +dist: >>>>>>>> + @$(PAK) >>>>>>>> + >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> +# Installation Details >>>>>>>> +############################################################## >>>>>>>> ################# >>>>>>>> + >>>>>>>> +$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects)) >>>>>>>> + @$(PREBUILD) >>>>>>>> + @rm -rf $(DIR_APP) && cd $(DIR_SRC) >>>>>>>> + >>>>>>>> + #install cgi >>>>>>>> + install -v -m 755 $(DIR_CONF)/portredir/portredir.cgi >>>>>>>> /srv/web/ipfire/cgi-bin/ >>>>>>>> + >>>>>>>> + #create configuration dir >>>>>>>> + -mkdir -pv /var/ipfire/portredir/ >>>>>>>> + chown -R nobody:nobody /var/ipfire/portredir/ >>>>>>>> + >>>>>>>> + # Install include file for backup >>>>>>>> + install -v -m 644 $(DIR_CONF)/portredir/portredir- >>>>>>>> backup /var/ipfire/backup/addons/includes/portredir >>>>>>>> + >>>>>>>> + # Install menu file >>>>>>>> + install -v -m 644 $(DIR_CONF)/portredir/EX- >>>>>>>> portredir.menu /var/ipfire/menu.d/ >>>>>>>> + chown nobody:nobody /var/ipfire/menu.d/EX- >>>>>>>> portredir.menu >>>>>>>> + >>>>>>>> + # Install addon-specific language-files >>>>>>>> + install -v -m 644 >>>>>>>> $(DIR_CONF)/portredir/lang/portredir.*.pl /var/ipfire/addon- >>>>>>>> lang/ >>>>>>>> + >>>>>>>> + #install initscripts >>>>>>>> + $(call INSTALL_INITSCRIPT,portredir) >>>>>>>> + >>>>>>>> + # Create symlinks for runlevel interaction. >>>>>>>> + ln -svf /etc/rc.d/init.d/portredir >>>>>>>> /etc/rc.d/rc3.d/S23portredir >>>>>>>> + ln -svf /etc/rc.d/init.d/portredir >>>>>>>> /etc/rc.d/rc0.d/K77portredir >>>>>>>> + ln -svf /etc/rc.d/init.d/portredir >>>>>>>> /etc/rc.d/rc6.d/K77portredir >>>>>>>> + >>>>>>>> + @rm -rf $(DIR_APP) >>>>>>>> + @$(POSTBUILD) >>>>>>>> + >>>>>>>> diff --git a/make.sh b/make.sh >>>>>>>> index fc03ebcd5..ab9fe881a 100755 >>>>>>>> --- a/make.sh >>>>>>>> +++ b/make.sh >>>>>>>> @@ -1623,6 +1623,7 @@ buildipfire() { >>>>>>>> lfsmake2 socat >>>>>>>> lfsmake2 libcdada >>>>>>>> lfsmake2 pmacct >>>>>>>> + lfsmake2 portredir >>>>>>>> } >>>>>>>> >>>>>>>> buildinstaller() { >>>>>>>> diff --git a/src/initscripts/packages/portredir >>>>>>>> b/src/initscripts/packages/portredir >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..cc57fb9cc >>>>>>>> --- /dev/null >>>>>>>> +++ b/src/initscripts/packages/portredir >>>>>>>> @@ -0,0 +1,191 @@ >>>>>>>> +#!/bin/sh >>>>>>>> +############################################################## >>>>>>>> ########## >>>>>>>> +# Begin $rc_base/init.d/portredir >>>>>>>> +# >>>>>>>> +# Description : portredir init script for DNS/NTP and custom >>>>>>>> +# port redirection rules >>>>>>>> +# >>>>>>>> +############################################################## >>>>>>>> ########## >>>>>>>> + >>>>>>>> +. /etc/sysconfig/rc >>>>>>>> +. ${rc_functions} >>>>>>>> + >>>>>>>> +IPT="/sbin/iptables"; >>>>>>>> +parent_chain="PREROUTING"; >>>>>>>> +chain="PORT_REDIRECT"; >>>>>>>> + >>>>>>>> +confdir="/var/ipfire/portredir"; >>>>>>>> +settingsfile="${confdir}/settings"; >>>>>>>> +redirectsfile="${confdir}/redirects"; >>>>>>>> +SYSLOG="NO"; >>>>>>>> +VERBOSE="NO"; >>>>>>>> + >>>>>>>> +eval $(/usr/local/bin/readhash /var/ipfire/ethernet/settings); >>>>>>>> +eval $(/usr/local/bin/readhash ${settingsfile}); >>>>>>>> + >>>>>>>> +logtext() { >>>>>>>> + if [ "${SYSLOG}" = "YES" ]; then logger -t "portredir" >>>>>>>> ${1}; fi; >>>>>>>> + if [ "${VERBOSE}" = "YES" ]; then echo ${1}; fi;} >>>>>>>> + >>>>>>>> +create_chain() { >>>>>>>> + >>>>>>>> + local line=$(${IPT} -t nat -L ${parent_chain} --line- >>>>>>>> numbers |grep "SQUID" |awk '{printf($1)}'); >>>>>>>> + >>>>>>>> + if [[ "${REDIR_ENABLE_ADDON}" == "off" || -z >>>>>>>> "${REDIR_ENABLE_ADDON}" ]]; then >>>>>>>> + logtext "addon not enabled in web >>>>>>>> interface..."; >>>>>>>> + echo "Portredir addon not enabled in web >>>>>>>> interface..."; >>>>>>>> + exit 0; >>>>>>>> + fi; >>>>>>>> + >>>>>>>> + if [ -z "$(${IPT} -t nat -L ${parent_chain} |grep >>>>>>>> ${chain})" ]; then >>>>>>>> + ${IPT} -t nat -N ${chain}; >>>>>>>> + >>>>>>>> + if [ ! -z "${line}" ]; then >>>>>>>> + logtext "create chain ${chain} and link >>>>>>>> in ${parent_chain} at position ${line}..."; >>>>>>>> + ${IPT} -t nat -I ${parent_chain} >>>>>>>> ${line} -j ${chain}; >>>>>>>> + else >>>>>>>> + logtext "create chain ${chain} and link >>>>>>>> in ${parent_chain} at last position..."; >>>>>>>> + ${IPT} -t nat -A ${parent_chain} -j >>>>>>>> ${chain}; >>>>>>>> + fi >>>>>>>> + else >>>>>>>> + return 1; >>>>>>>> + fi; >>>>>>>> + return 0; >>>>>>>> +} >>>>>>>> + >>>>>>>> +remove_chain() { >>>>>>>> + if [ ! -z "$(${IPT} -t nat -L ${parent_chain} |grep >>>>>>>> ${chain})" ]; then >>>>>>>> + logtext "remove chain ${chain} and link in >>>>>>>> ${parent_chain} from system..."; >>>>>>>> + ${IPT} -t nat -D "${parent_chain}" -j ${chain}; >>>>>>>> + ${IPT} -t nat -F ${chain}; >>>>>>>> + ${IPT} -t nat -X ${chain}; >>>>>>>> + else >>>>>>>> + return 1; >>>>>>>> + fi; >>>>>>>> + return 0; >>>>>>>> +} >>>>>>>> + >>>>>>>> +activate_custom_redirections() { >>>>>>>> + >>>>>>>> + local array=(); >>>>>>>> + local redirects=(); >>>>>>>> + local i; >>>>>>>> + index=(); >>>>>>>> + iface=(); >>>>>>>> + protocol=(); >>>>>>>> + port=(); >>>>>>>> + targetip=(); >>>>>>>> + enabled=(); >>>>>>>> + >>>>>>>> + IFS=$'\n' read -d '' -ra redirects < ${redirectsfile}; >>>>>>>> + >>>>>>>> + for i in "${!redirects[@]}" >>>>>>>> + do >>>>>>>> + IFS=$',' read -ra array <<< ${redirects[i]}; >>>>>>>> + index[i]=${array[0]}; >>>>>>>> + iface[i]=${array[1]}; >>>>>>>> + protocol[i]=${array[2]}; >>>>>>>> + port[i]=${array[3]}; >>>>>>>> + targetip[i]=${array[4]}; >>>>>>>> + enabled[i]=${array[5]}; >>>>>>>> + done >>>>>>>> + >>>>>>>> + for i in "${!index[@]}" >>>>>>>> + do >>>>>>>> + if [[ ! -z "${GREEN_DEV}" && "${iface[i]}" = >>>>>>>> "green" && "${enabled[i]}" = "enabled" ]]; then >>>>>>>> + >>>>>>>> + logtext "add redirect in ${chain} on >>>>>>>> ${GREEN_DEV} ip ${targetip[i]} protocol ${protocol[i]} port >>>>>>>> ${port[i]} "; >>>>>>>> + ${IPT} -t nat -A ${chain} -i >>>>>>>> ${GREEN_DEV} -d ${targetip[i]} -p ${protocol[i]} -m >>>>>>>> ${protocol[i]} --dport ${port[i]} -j RETURN; >>>>>>>> + ${IPT} -t nat -A ${chain} -i >>>>>>>> ${GREEN_DEV} -p ${protocol[i]} -m ${protocol[i]} --dport >>>>>>>> ${port[i]} -j REDIRECT; >>>>>>>> + fi >>>>>>>> + if [[ ! -z "${BLUE_DEV}" && "${iface[i]}" = >>>>>>>> "blue" && "${enabled[i]}" = "enabled" ]]; then >>>>>>>> + logtext "add redirect in ${chain} on >>>>>>>> ${BLUE_DEV} ip ${targetip[i]} protocol ${protocol[i]} port >>>>>>>> ${port[i]} "; >>>>>>>> + ${IPT} -t nat -A ${chain} -i >>>>>>>> ${BLUE_DEV} -d ${targetip[i]} -p ${protocol[i]} -m >>>>>>>> ${protocol[i]} --dport ${port[i]} -j RETURN; >>>>>>>> + ${IPT} -t nat -A ${chain} -i >>>>>>>> ${BLUE_DEV} -p ${protocol[i]} -m ${protocol[i]} --dport >>>>>>>> ${port[i]} -j REDIRECT; >>>>>>>> + fi >>>>>>>> + if [[ ! -z "${ORANGE_DEV}" && "${iface[i]}" = >>>>>>>> "orange" && "${enabled[i]}" = "enabled" ]]; then >>>>>>>> + logtext "add redirect in ${chain} on >>>>>>>> ${ORANGE_DEV} ip ${targetip[i]} protocol ${protocol[i]} port >>>>>>>> ${port[i]} "; >>>>>>>> + ${IPT} -t nat -A ${chain} -i >>>>>>>> ${ORANGE_DEV} -d ${targetip[i]} -p ${protocol[i]} -m >>>>>>>> ${protocol[i]} --dport ${port[i]} -j RETURN; >>>>>>>> + ${IPT} -t nat -A ${chain} -i >>>>>>>> ${ORANGE_DEV} -p ${protocol[i]} -m ${protocol[i]} --dport >>>>>>>> ${port[i]} -j REDIRECT; >>>>>>>> + fi >>>>>>>> + done >>>>>>>> + unset array redirects i index iface protocol port >>>>>>>> targetip enabled; >>>>>>>> + return 0; >>>>>>>> +} >>>>>>>> + >>>>>>>> +activate_redirections() { >>>>>>>> + >>>>>>>> + if ! create_chain; then return 1; fi; >>>>>>>> + >>>>>>>> + # Force DNS REDIRECTs on GREEN (udp, tcp, 53) >>>>>>>> + if [[ "${REDIR_DNS_GREEN}" == "on" && >>>>>>>> "${REDIR_CUSTOM_GREEN}" = "off" ]]; then >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d >>>>>>>> ${GREEN_ADDRESS} -p udp -m udp --dport domain -j RETURN; >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p >>>>>>>> udp -m udp --dport domain -j REDIRECT; >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d >>>>>>>> ${GREEN_ADDRESS} -p tcp -m tcp --dport domain -j RETURN; >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p >>>>>>>> tcp -m tcp --dport domain -j REDIRECT; >>>>>>>> + fi >>>>>>>> + >>>>>>>> + # Force DNS REDIRECTs on BLUE (udp, tcp, 53) >>>>>>>> + if [[ "${REDIR_DNS_BLUE}" == "on" && >>>>>>>> "${REDIR_CUSTOM_BLUE}" = "off" ]]; then >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d >>>>>>>> ${BLUE_ADDRESS} -p udp -m udp --dport domain -j RETURN >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p udp >>>>>>>> -m udp --dport domain -j REDIRECT >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d >>>>>>>> ${BLUE_ADDRESS} -p tcp -m tcp --dport domain -j RETURN >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p tcp >>>>>>>> -m tcp --dport domain -j REDIRECT >>>>>>>> + fi >>>>>>>> + >>>>>>>> + # Force DNS REDIRECTs on ORANGE (udp, tcp, 53) >>>>>>>> + if [[ "${REDIR_DNS_ORANGE}" == "on" && >>>>>>>> "${REDIR_CUSTOM_ORANGE}" = "off" ]]; then >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -d >>>>>>>> ${ORANGE_ADDRESS} -p udp -m udp --dport domain -j RETURN >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p >>>>>>>> udp -m udp --dport domain -j REDIRECT >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -d >>>>>>>> ${ORANGE_ADDRESS} -p tcp -m tcp --dport domain -j RETURN >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p >>>>>>>> tcp -m tcp --dport domain -j REDIRECT >>>>>>>> + fi >>>>>>>> + >>>>>>>> + # Force NTP REDIRECTs on GREEN (udp, 123) >>>>>>>> + if [[ "${REDIR_NTP_GREEN}" == "on" && >>>>>>>> "${REDIR_CUSTOM_GREEN}" = "off" ]]; then >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -d >>>>>>>> ${GREEN_ADDRESS} -p udp -m udp --dport ntp -j RETURN >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${GREEN_DEV} -p >>>>>>>> udp -m udp --dport ntp -j REDIRECT >>>>>>>> + fi >>>>>>>> + >>>>>>>> + # Force NTP REDIRECTs on BLUE (udp, 123) >>>>>>>> + if [[ "${REDIR_NTP_BLUE}" == "on" && >>>>>>>> "${REDIR_CUSTOM_BLUE}" = "off" ]]; then >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -d >>>>>>>> ${BLUE_ADDRESS} -p udp -m udp --dport ntp -j RETURN >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${BLUE_DEV} -p udp >>>>>>>> -m udp --dport ntp -j REDIRECT >>>>>>>> + fi >>>>>>>> + >>>>>>>> + # Force NTP REDIRECTs on ORANGE (udp, 123) >>>>>>>> + if [[ "${REDIR_NTP_ORANGE}" == "on" && >>>>>>>> "${REDIR_CUSTOM_ORANGE}" = "off" ]]; then >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -d >>>>>>>> ${ORANGE_ADDRESS} -p udp -m udp --dport ntp -j RETURN >>>>>>>> + ${IPT} -t nat -A ${chain} -i ${ORANGE_DEV} -p >>>>>>>> udp -m udp --dport ntp -j REDIRECT >>>>>>>> + fi >>>>>>>> + >>>>>>>> + if ! activate_custom_redirections; then return 1; fi; >>>>>>>> + >>>>>>>> + return 0; >>>>>>>> +} >>>>>>>> + >>>>>>>> +case "${1}" in >>>>>>>> + start) >>>>>>>> + boot_mesg "Loading port redirections..." >>>>>>>> + activate_redirections; >>>>>>>> + evaluate_retval; >>>>>>>> + ;; >>>>>>>> + >>>>>>>> + stop) >>>>>>>> + boot_mesg "Removing port redirections..." >>>>>>>> + remove_chain; >>>>>>>> + evaluate_retval; >>>>>>>> + ;; >>>>>>>> + >>>>>>>> + restart) >>>>>>>> + ${0} stop >>>>>>>> + ${0} start >>>>>>>> + ;; >>>>>>>> + >>>>>>>> + *) >>>>>>>> + echo "Usage: ${0} {start|stop|restart}" >>>>>>>> + exit 1 >>>>>>>> + ;; >>>>>>>> +esac >>>>>>>> + >>>>>>>> +# End $rc_base/init.d/portredir >>>>>>>> diff --git a/src/misc-progs/Makefile b/src/misc-progs/Makefile >>>>>>>> index 7c3ef7529..850f8fdcc 100644 >>>>>>>> --- a/src/misc-progs/Makefile >>>>>>>> +++ b/src/misc-progs/Makefile >>>>>>>> @@ -30,7 +30,7 @@ SUID_PROGS = squidctrl sshctrl ipfirereboot \ >>>>>>>> wirelessctrl getipstat qosctrl \ >>>>>>>> redctrl syslogdctrl extrahdctrl sambactrl \ >>>>>>>> smartctrl clamavctrl addonctrl pakfire mpfirectrl >>>>>>>> wlanapctrl \ >>>>>>>> - setaliases urlfilterctrl updxlratorctrl fireinfoctrl >>>>>>>> rebuildroutes \ >>>>>>>> + setaliases urlfilterctrl updxlratorctrl fireinfoctrl >>>>>>>> rebuildroutes portredirctrl \ >>>>>>>> getconntracktable wirelessclient torctrl ddnsctrl >>>>>>>> unboundctrl \ >>>>>>>> captivectrl >>>>>>>> >>>>>>>> diff --git a/src/misc-progs/portredirctrl.c b/src/misc- >>>>>>>> progs/portredirctrl.c >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..7897d711c >>>>>>>> --- /dev/null >>>>>>>> +++ b/src/misc-progs/portredirctrl.c >>>>>>>> @@ -0,0 +1,47 @@ >>>>>>>> +/* This file is part of the IPFire Firewall. >>>>>>>> + * >>>>>>>> + * This program is distributed under the terms of the GNU >>>>>>>> General Public >>>>>>>> + * Licence. See the file COPYING for details. >>>>>>>> + * >>>>>>>> + */ >>>>>>>> + >>>>>>>> +#include >>>>>>>> +#include >>>>>>>> +#include >>>>>>>> +#include >>>>>>>> +#include >>>>>>>> +#include >>>>>>>> +#include "setuid.h" >>>>>>>> + >>>>>>>> +int main(int argc, char *argv[]) { >>>>>>>> + if (!(initsetuid())) >>>>>>>> + exit(1); >>>>>>>> + >>>>>>>> + // Check what command is asked >>>>>>>> + if (argc < 2) { >>>>>>>> + fprintf(stderr, "\nNo argument >>>>>>>> given.\n\nportredirctrl >>>>>>>> (start|stop|restart|enable|disable)\n\n"); >>>>>>>> + exit(1); >>>>>>>> + } >>>>>>>> + >>>>>>>> + if (strcmp(argv[1], "start") == 0) { >>>>>>>> + safe_system("/etc/rc.d/init.d/portredir >>>>>>>> start"); >>>>>>>> + } else if (strcmp(argv[1], "stop") == 0) { >>>>>>>> + safe_system("/etc/rc.d/init.d/portredir >>>>>>>> stop"); >>>>>>>> + } else if (strcmp(argv[1], "restart") == 0) { >>>>>>>> + safe_system("/etc/rc.d/init.d/portredir >>>>>>>> restart"); >>>>>>>> + } else if (strcmp(argv[1], "enable") == 0) { >>>>>>>> + safe_system("touch >>>>>>>> /var/ipfire/portredir/enable"); >>>>>>>> + safe_system("ln -snf /etc/rc.d/init.d/portredir >>>>>>>> /etc/rc.d/rc3.d/S23portredir >/dev/null 2>&1"); >>>>>>>> + safe_system("ln -snf /etc/rc.d/init.d/portredir >>>>>>>> /etc/rc.d/rc0.d/K77portredir >/dev/null 2>&1"); >>>>>>>> + safe_system("ln -snf /etc/rc.d/init.d/portredir >>>>>>>> /etc/rc.d/rc6.d/K77portredir >/dev/null 2>&1"); >>>>>>>> + } else if (strcmp(argv[1], "disable") == 0) { >>>>>>>> + safe_system("/etc/rc.d/init.d/portredir stop"); >>>>>>>> + safe_system("unlink >>>>>>>> /var/ipfire/portredir/enable"); >>>>>>>> + safe_system("rm -rf /etc/rc.d/rc*.d/*portredir >>>>>>>>> /dev/null 2>&1"); >>>>>>>> + } else { >>>>>>>> + fprintf(stderr, "\nBad argument >>>>>>>> given.\n\nportredirctrl >>>>>>>> (start|stop|restart|enable|disable)\n\n"); >>>>>>>> + exit(1); >>>>>>>> + } >>>>>>>> + >>>>>>>> + return 0; >>>>>>>> +} >>>>>>>> diff --git a/src/paks/portredir/install.sh >>>>>>>> b/src/paks/portredir/install.sh >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..9f69aeae2 >>>>>>>> --- /dev/null >>>>>>>> +++ b/src/paks/portredir/install.sh >>>>>>>> @@ -0,0 +1,32 @@ >>>>>>>> +#!/bin/bash >>>>>>>> +############################################################## >>>>>>>> ############## >>>>>>>> +# >>>>>>>> # >>>>>>>> +# This file is part of the IPFire >>>>>>>> Firewall. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire 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. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire 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 IPFire; if not, write to the Free >>>>>>>> Software # >>>>>>>> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA >>>>>>>> 02111-1307 USA # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# Copyright (C) 2021 IPFire-Team >>>>>>>> . # >>>>>>>> +# >>>>>>>> # >>>>>>>> +############################################################## >>>>>>>> ############## >>>>>>>> +# >>>>>>>> +. /opt/pakfire/lib/functions.sh >>>>>>>> +extract_files >>>>>>>> +restore_backup ${NAME} >>>>>>>> + >>>>>>>> +/usr/local/bin/update-lang-cache >>>>>>>> + >>>>>>>> +chown root:nobody /usr/local/bin/portredirctrl >>>>>>>> +chmod 4750 /usr/local/bin/portredirctrl >>>>>>>> +chmod u+s /usr/local/bin/portredirctrl >>>>>>>> diff --git a/src/paks/portredir/uninstall.sh >>>>>>>> b/src/paks/portredir/uninstall.sh >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..df9270125 >>>>>>>> --- /dev/null >>>>>>>> +++ b/src/paks/portredir/uninstall.sh >>>>>>>> @@ -0,0 +1,28 @@ >>>>>>>> +#!/bin/bash >>>>>>>> +############################################################## >>>>>>>> ############## >>>>>>>> +# >>>>>>>> # >>>>>>>> +# This file is part of the IPFire >>>>>>>> Firewall. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire 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. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire 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 IPFire; if not, write to the Free >>>>>>>> Software # >>>>>>>> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA >>>>>>>> 02111-1307 USA # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# Copyright (C) 2007 IPFire-Team >>>>>>>> . # >>>>>>>> +# >>>>>>>> # >>>>>>>> +############################################################## >>>>>>>> ############## >>>>>>>> +# >>>>>>>> +. /opt/pakfire/lib/functions.sh >>>>>>>> +make_backup ${NAME} >>>>>>>> +remove_files >>>>>>>> + >>>>>>>> +/usr/local/bin/update-lang-cache >>>>>>>> diff --git a/src/paks/portredir/update.sh >>>>>>>> b/src/paks/portredir/update.sh >>>>>>>> new file mode 100644 >>>>>>>> index 000000000..89c40d0d7 >>>>>>>> --- /dev/null >>>>>>>> +++ b/src/paks/portredir/update.sh >>>>>>>> @@ -0,0 +1,26 @@ >>>>>>>> +#!/bin/bash >>>>>>>> +############################################################## >>>>>>>> ############## >>>>>>>> +# >>>>>>>> # >>>>>>>> +# This file is part of the IPFire >>>>>>>> Firewall. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire 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. # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# IPFire 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 IPFire; if not, write to the Free >>>>>>>> Software # >>>>>>>> +# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA >>>>>>>> 02111-1307 USA # >>>>>>>> +# >>>>>>>> # >>>>>>>> +# Copyright (C) 2007 IPFire-Team >>>>>>>> . # >>>>>>>> +# >>>>>>>> # >>>>>>>> +############################################################## >>>>>>>> ############## >>>>>>>> +# >>>>>>>> +. /opt/pakfire/lib/functions.sh >>>>>>>> +./uninstall.sh >>>>>>>> +./install.sh >>>>>>>> -- >>>>>>>> 2.18.0 >>>>>>>> >>>>>>> >>>>>> >>>>> >>>> >>> >> >