From: Michael Tremer <michael.tremer@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH] New addon: Portredirect 1.0
Date: Thu, 05 Aug 2021 22:33:32 +0200 [thread overview]
Message-ID: <147F4AEF-0264-4B59-AB39-D87B68883D17@ipfire.org> (raw)
In-Reply-To: <CD95E831-4AE9-40B7-BB91-27B3F3164270@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 74063 bytes --]
Hello,
> On 3 Aug 2021, at 18:04, Jon Murphy <jcmurphy26(a)gmail.com> wrote:
>
> Hello all!
>
> I’m having trouble following the changes to firewall.cgi. I think there were 4 or 5 patches
> submitted to the Dev Mailing List.
>
> Did these get approved?
That is a good question. AFAIK they are not in c159.
>
> I looked at the Changelog for Core 158 and core 159 (testing) but I didn’t see anything:
>
> https://nightly.ipfire.org/core158/2021-07-21%2015:47:35%20+0000-23498c61/x86_64/changelog.txt
>
> https://nightly.ipfire.org/master/latest/x86_64/changelog.txt
>
>
> Can they be added to CU 159?
>
> To be honest I am mainly interested in the DNS redirect (and its cousin NTP redirect).
>
> I’d be happy to help test but I do need some help applying the patches.
> Right now I apply them by grabbing a copy of firewall.cgi and manually deleting and then manually adding a patch.
> Not the smartest way but it works (if I don’t screw-up and make a mistake!).
@Stefan: What is the status on this?
-Michael
> Jon
>
>> On Jun 30, 2021, at 2:14 PM, Stefan Schantl <stefan.schantl(a)ipfire.org> 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 <jcmurphy26(a)gmail.com> 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 <marcel.lorenz(a)ipfire.org>
>>>>>
>>>>> 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 <matthias.fischer(a)ipfire.org>
>>>>>> ---
>>>>>> 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
>>>>>> <info(a)ipfire.org> #
>>>>>> +#
>>>>>> #
>>>>>> +# 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 "<font color='red'>$errormessage </font>";
>>>>>> + &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 "<form method='post'
>>>>>> action='$ENV{'SCRIPT_NAME'}'>";
>>>>>> +
>>>>>> +print <<END;
>>>>>> +<table width='80%' cellspacing='0' border='0'>
>>>>>> + <tr><td colspan='2' class='base'
>>>>>> bgcolor='$color{'color20'}'><b>$Lang::tr{'portredir common
>>>>>> settings'}</b></td></tr
>>>>>> + <tr>
>>>>>> + <td width='25%'
>>>>>> class='base'>$Lang::tr{'portredir enable addon'}:</td>
>>>>>> + <td><input type='checkbox'
>>>>>> name='REDIR_ENABLE_ADDON' $checked{'REDIR_ENABLE_ADDON'}{'on'}
>>>>>> /></td>
>>>>>> + </tr>
>>>>>> + <tr><td colspan='2'></td></tr>
>>>>>> + <tr><td colspan='2'> </td></tr>
>>>>>> +END
>>>>>> +
>>>>>> + # create html table with header line 1
>>>>>> + print "<table width='80%' cellspacing='0'
>>>>>> border='0'><tr>";
>>>>>> + print "<th class='base' width='40%'
>>>>>> align='left'><b>$Lang::tr{'portredir fw for interface'}</th>";
>>>>>> + if ($netsettings{'GREEN_DEV'}) {print "<th
>>>>>> class='base' width='10%'><b><font
>>>>>> color=green>$Lang::tr{'green'}</font></th>";
>>>>>> + } else { print "<th
>>>>>> class='base' width='10%'></font></th>"; }
>>>>>> + if ($netsettings{'BLUE_DEV'}) {print "<th
>>>>>> class='base' width='10%'><b><font
>>>>>> color=blue>$Lang::tr{'blue'}</font></th>";
>>>>>> + } else { print "<th
>>>>>> class='base' width='10%'></font></th>"; }
>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print "<th
>>>>>> class='base' width='10%'><b><font
>>>>>> color=orange>$Lang::tr{'orange'}</font></th>";
>>>>>> + } else { print "<th
>>>>>> class='base' width='10%'></font></th>"; }
>>>>>> +
>>>>>> + # the empty right row
>>>>>> + print "<th class='base'
>>>>>> width='30%'><td></td></th></tr>";
>>>>>> +
>>>>>> + # line 2
>>>>>> + print "<tr><td>$Lang::tr{'portredir force local
>>>>>> dns'}</td>";
>>>>>> + if ($netsettings{'GREEN_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_DNS_GREEN'
>>>>>> $checked{'REDIR_DNS_GREEN'}{'on'}></td>";} else { print
>>>>>> "<td></td>";}
>>>>>> + if ($netsettings{'BLUE_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_DNS_BLUE' $checked{'REDIR_DNS_BLUE'}{'on'}></td>";}
>>>>>> else { print "<td></td>";}
>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_DNS_ORANGE'
>>>>>> $checked{'REDIR_DNS_ORANGE'}{'on'}></td>";} else { print
>>>>>> "<td></td>";}
>>>>>> +
>>>>>> + # line 3
>>>>>> + print "</tr><tr><td>$Lang::tr{'portredir force local
>>>>>> ntp'}</td>";
>>>>>> + if ($netsettings{'GREEN_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_NTP_GREEN'
>>>>>> $checked{'REDIR_NTP_GREEN'}{'on'}></td>";} else { print
>>>>>> "<td></td>";}
>>>>>> + if ($netsettings{'BLUE_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_NTP_BLUE' $checked{'REDIR_NTP_BLUE'}{'on'}></td>";}
>>>>>> else { print "<td></td>";}
>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_NTP_ORANGE'
>>>>>> $checked{'REDIR_NTP_ORANGE'}{'on'}></td>";} else { print
>>>>>> "<td></td>";}
>>>>>> +
>>>>>> + # line 4
>>>>>> + print "</tr><tr><td>$Lang::tr{'portredir enable user
>>>>>> redirections'}</td>";
>>>>>> + if ($netsettings{'GREEN_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_CUSTOM_GREEN'
>>>>>> $checked{'REDIR_CUSTOM_GREEN'}{'on'}></td>";} else { print
>>>>>> "<td></td>";}
>>>>>> + if ($netsettings{'BLUE_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_CUSTOM_BLUE'
>>>>>> $checked{'REDIR_CUSTOM_BLUE'}{'on'}></td>";} else { print
>>>>>> "<td></td>";}
>>>>>> + if ($netsettings{'ORANGE_DEV'}) {print "<td
>>>>>> class='base' align='center'><input type='checkbox'
>>>>>> name='REDIR_CUSTOM_ORANGE'
>>>>>> $checked{'REDIR_CUSTOM_ORANGE'}{'on'}></td>";} else { print
>>>>>> "<td></td>";}
>>>>>> +
>>>>>> + print <<END;
>>>>>> + </tr></table>
>>>>>> + <table width='80%' cellspacing='0' border='0'>
>>>>>> + <tr><td colspan='2'> </td></tr>
>>>>>> + <tr><td align='left'><b>$Lang::tr{'portredir
>>>>>> save to activate'}</b></td><td width='5%' align='center'><input
>>>>>> type='submit' name='ACTION' value=' $Lang::tr{'save'}
>>>>>> '></td></tr>
>>>>>> + </table></form>
>>>>>> +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;
>>>>>> + <table width='80%' cellspacing='1' border='0'>
>>>>>> + <tr>
>>>>>> + <td class='base'
>>>>>> bgcolor='$color{'color20'}'
>>>>>> align='center'><b>$Lang::tr{'interface'}</b></td>
>>>>>> + <td class='base'
>>>>>> bgcolor='$color{'color20'}'
>>>>>> align='center'><b>$Lang::tr{'protocol'}</b></td>
>>>>>> + <td class='base'
>>>>>> bgcolor='$color{'color20'}'
>>>>>> align='center'><b>$Lang::tr{'port'}</b></td>
>>>>>> + <td class='base'
>>>>>> bgcolor='$color{'color20'}' align='center'><b>$Lang::tr{'ip
>>>>>> address'}</b></td>
>>>>>> + <td class='base'
>>>>>> bgcolor='$color{'color20'}'
>>>>>> align='center'><b>$Lang::tr{'remark'}</b></td>
>>>>>> + <td class='base' colspan='3'
>>>>>> bgcolor='$color{'color20'}'></td>
>>>>>> + </tr>
>>>>>> +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;
>>>>>> + <tr>
>>>>>> + <td width='15%'
>>>>>> class='base' align='center' $col><b><font
>>>>>> color=$interface>$Lang::tr{$interface}</font></b></td>
>>>>>> + <td width='10%'
>>>>>> class='base' align='center' $col>$protocol</td>
>>>>>> + <td width='10%'
>>>>>> class='base' align='center' $col>$port</td>
>>>>>> + <td width='15%'
>>>>>> class='base' align='center' $col> $address</td>
>>>>>> + <td width='40%'
>>>>>> class='base' align='center' $col> $remark</td>
>>>>>> + <td
>>>>>> align='center' $col>
>>>>>> + <form
>>>>>> method='post' action='$ENV{'SCRIPT_NAME'}'>
>>>>>> +
>>>>>> <input type='hidden' name='ACTION' value='$Lang::tr{'toggle
>>>>>> enable disable'}' />
>>>>>> +
>>>>>> <input type='image' name='$Lang::tr{'toggle enable disable'}'
>>>>>> src='/images/$gif' alt='$gdesc' title='$gdesc' />
>>>>>> +
>>>>>> <input type='hidden' name='ID' value='$key' />
>>>>>> + </form>
>>>>>> + </td>
>>>>>> + <td
>>>>>> align='center' $col>
>>>>>> + <form
>>>>>> method='post' action='$ENV{'SCRIPT_NAME'}'>
>>>>>> +
>>>>>> <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'}' />
>>>>>> +
>>>>>> <input type='hidden' name='ID' value='$key' />
>>>>>> + </form>
>>>>>> + </td>
>>>>>> + <td
>>>>>> align='center' $col>
>>>>>> + <form
>>>>>> method='post' name='$key' action='$ENV{'SCRIPT_NAME'}'>
>>>>>> +
>>>>>> <input type='image' name='$Lang::tr{'remove'}'
>>>>>> src='/images/delete.gif' title='$Lang::tr{'remove'}'
>>>>>> alt='$Lang::tr{'remove'}'>
>>>>>> +
>>>>>> <input type='hidden' name='ID' value='$key'>
>>>>>> +
>>>>>> <input type='hidden' name='ACTION'
>>>>>> value='$Lang::tr{'remove'}'>
>>>>>> + </form>
>>>>>> + </td>
>>>>>> + </tr>
>>>>>> +END
>>>>>> + }
>>>>>> + } else {
>>>>>> + # Print notice that currently
>>>>>> no ports are redirected.
>>>>>> + print "<tr>\n";
>>>>>> + print "<td class='base'
>>>>>> colspan='2'>$Lang::tr{'portredir no entries'}</td>\n";
>>>>>> + print "</tr>\n";
>>>>>> + }
>>>>>> +
>>>>>> + print "</table>\n";
>>>>>> +
>>>>>> + # Section to add new elements or edit existing ones.
>>>>>> + print <<END;
>>>>>> + <br>
>>>>>> + <hr>
>>>>>> + <br>
>>>>>> + <div align='center'>
>>>>>> + <table width='100%' cellspacing='0' border='0'>
>>>>>> +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 "<tr><td class='boldbase'
>>>>>> colspan='6'><b>$Lang::tr{'update'}</b></td></tr>\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 "<tr><td class='boldbase'
>>>>>> colspan='11'><b>$Lang::tr{'dnsforward add a new
>>>>>> entry'}</b></td></tr>\n";
>>>>>> + print "<tr><td> </td></tr>\n";
>>>>>> + }
>>>>>> +
>>>>>> + print <<END;
>>>>>> + <tr>
>>>>>> + <td class='base' width='1%'
>>>>>> bgcolor='$color{'color22'}'></td>
>>>>>> + <td class='base' width='15%'
>>>>>> bgcolor='$color{'color22'}'
>>>>>> align='left'><b>$Lang::tr{'interface'}</b></td>
>>>>>> + <td class='base' width='10%'
>>>>>> bgcolor='$color{'color22'}'
>>>>>> align='left'><b>$Lang::tr{'protocol'}</b></td>
>>>>>> + <td class='base' width='10%'
>>>>>> bgcolor='$color{'color22'}'
>>>>>> align='left'> <b>$Lang::tr{'port'}</b></td>
>>>>>> + <td class='base' width='13%'
>>>>>> bgcolor='$color{'color22'}' align='left'> <b>$Lang::tr{'ip
>>>>>> address'}</b></td>
>>>>>> + <td class='base' width='30%'
>>>>>> bgcolor='$color{'color22'}'
>>>>>> align='left'> <b>$Lang::tr{'remark'}</b></td>
>>>>>> + <td class='base' width='15%'
>>>>>> bgcolor='$color{'color22'}'></td>
>>>>>> + <td class='base' width='1%'
>>>>>> bgcolor='$color{'color22'}'></td>
>>>>>> + </tr>
>>>>>> +
>>>>>> + <form method='post'
>>>>>> action='$ENV{'SCRIPT_NAME'}'>
>>>>>> + <input type='hidden' name='ID'
>>>>>> value='$settings{'ID'}'>
>>>>>> + <tr>
>>>>>> + <td class='base'></td>
>>>>>> + <td><select style='width:90px;'
>>>>>> id='interface' name='REDIR_ENTRY_INTERFACE'>
>>>>>> +END
>>>>>> + if ($netsettings{'GREEN_DEV'})
>>>>>> {
>>>>>> + if ($entry_interface eq
>>>>>> "green") {
>>>>>> + print "<option
>>>>>> value='green' selected='selected'
>>>>>> {'green'}>$Lang::tr{'green'}</option>";
>>>>>> + } else { print "<option
>>>>>> value='green' {'green'}>$Lang::tr{'green'}</option>";}
>>>>>> + }
>>>>>> + if ($netsettings{'BLUE_DEV'}) {
>>>>>> + if ($entry_interface eq
>>>>>> "blue") {
>>>>>> + print "<option
>>>>>> value='blue' selected='selected'
>>>>>> {'blue'}>$Lang::tr{'blue'}</option>";
>>>>>> + } else { print "<option
>>>>>> value='blue' {'blue'}>$Lang::tr{'blue'}</option>";}
>>>>>> + }
>>>>>> + if ($netsettings{'ORANGE_DEV'})
>>>>>> {
>>>>>> + if ($entry_interface eq
>>>>>> "orange") {
>>>>>> + print "<option
>>>>>> value='orange' selected='selected'
>>>>>> {'orange'}>$Lang::tr{'orange'}</option>";
>>>>>> + } else { print "<option
>>>>>> value='orange' {'orange'}>$Lang::tr{'orange'}</option>";}
>>>>>> + }
>>>>>> +
>>>>>> + print "</select><td><select
>>>>>> style='width:50px;' name='REDIR_ENTRY_PROTOCOL'>";
>>>>>> + if ((!$entry_protocol) ||
>>>>>> ($entry_protocol eq "tcp")) {
>>>>>> + print "<option
>>>>>> selected='selected' id='protocol' value='tcp'
>>>>>> {'tcp'}>tcp</option>";
>>>>>> + print "<option value='udp'
>>>>>> {'udp'}>udp</option>";
>>>>>> + } elsif ($entry_protocol eq "udp") {
>>>>>> + print "<option value='tcp'
>>>>>> {'tcp'}>tcp</option>";
>>>>>> + print "<option
>>>>>> selected='selected' value='udp' {'udp'}>udp</option>";
>>>>>> + }
>>>>>> + print <<END;
>>>>>> + </select></td>
>>>>>> + <td><input type='text'
>>>>>> name='REDIR_ENTRY_PORT' value='$entry_port'
>>>>>> size='4'></td>
>>>>>> + <td><input type='text'
>>>>>> name='REDIR_ENTRY_ADDRESS' value='$entry_address'
>>>>>> size='14'></td>
>>>>>> + <td><input type='text'
>>>>>> name='REDIR_ENTRY_REMARK' value='$entry_remark'
>>>>>> size='35'></td>
>>>>>> + <td width='10%'
>>>>>> align='center'><input type='submit' name='ACTION' value='
>>>>>> $buttontext '></td>
>>>>>> + <td class='base'></td>
>>>>>> + </tr>
>>>>>> + </form>
>>>>>> + </table>
>>>>>> + </div>
>>>>>> +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
>>>>>> <info(a)ipfire.org> #
>>>>>> +#
>>>>>> #
>>>>>> +# 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 <stdlib.h>
>>>>>> +#include <stdio.h>
>>>>>> +#include <string.h>
>>>>>> +#include <unistd.h>
>>>>>> +#include <sys/types.h>
>>>>>> +#include <fcntl.h>
>>>>>> +#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
>>>>>> <info(a)ipfire.org>. #
>>>>>> +#
>>>>>> #
>>>>>> +##############################################################
>>>>>> ##############
>>>>>> +#
>>>>>> +. /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
>>>>>> <info(a)ipfire.org>. #
>>>>>> +#
>>>>>> #
>>>>>> +##############################################################
>>>>>> ##############
>>>>>> +#
>>>>>> +. /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
>>>>>> <info(a)ipfire.org>. #
>>>>>> +#
>>>>>> #
>>>>>> +##############################################################
>>>>>> ##############
>>>>>> +#
>>>>>> +. /opt/pakfire/lib/functions.sh
>>>>>> +./uninstall.sh
>>>>>> +./install.sh
>>>>>> --
>>>>>> 2.18.0
>>>>>>
>>>>>
>>>>
>>>
>>
>
next parent reply other threads:[~2021-08-05 20:33 UTC|newest]
Thread overview: 9+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CD95E831-4AE9-40B7-BB91-27B3F3164270@gmail.com>
2021-08-05 20:33 ` Michael Tremer [this message]
2021-08-06 15:57 ` Stefan Schantl
[not found] <6EBF1B5C-79B2-4258-B117-C2A4EB16CCFD@gmail.com>
2021-07-05 12:08 ` Stefan Schantl
[not found] <E41194E1-4002-4960-BF73-F57D6BCCD152@gmail.com>
2021-07-05 12:07 ` Stefan Schantl
[not found] <ADA23788-C972-417C-8F55-DD9D3B335BE9@gmail.com>
2021-07-01 15:24 ` Michael Tremer
[not found] <A699ABA7-74D3-4551-A981-E2E3A0935F8E@gmail.com>
2021-07-01 8:08 ` Michael Tremer
[not found] <305D680D-4D10-4D99-9F1D-3589BDF08FA9@gmail.com>
2021-06-28 17:56 ` Michael Tremer
2021-06-27 13:48 Matthias Fischer
2021-06-28 16:04 ` Michael Tremer
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=147F4AEF-0264-4B59-AB39-D87B68883D17@ipfire.org \
--to=michael.tremer@ipfire.org \
--cc=development@lists.ipfire.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox