public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
From: Stefan Schantl <stefan.schantl@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH] New addon: Portredirect 1.0
Date: Mon, 05 Jul 2021 14:08:56 +0200	[thread overview]
Message-ID: <4e894b4a343a57c8609665e4f350400e3ec70d15.camel@ipfire.org> (raw)
In-Reply-To: <6EBF1B5C-79B2-4258-B117-C2A4EB16CCFD@gmail.com>

[-- Attachment #1: Type: text/plain, Size: 128749 bytes --]

Hello Jon,

yes please file both as bugs on bugzilla.

Thanks in advance,

-Stefan
> Stefan,
> 
> Please let me know if I should enter this (and the one below) in
> bugzilla.
> 
> On other issue (small).  If I disable logging (and click apply
> changes) the logging does not stop. 
> 
> 
> (One image enclosed)
> 
> So when the DNS redirect firewall rule is on, then there are
> bazillions of log entries.  Not sure how to disable.  
> 
> Also, it looks like the iptables are correct.  Looking at the 2nd
> image: the left side - logging disabled.  Right is logging enabled.
> 
> 
> (One more image enclosed)
> 
> 
> Jon
> 
> 
> 
> 
> > On Jul 1, 2021, at 10:55 AM, Jon Murphy <jcmurphy26(a)gmail.com>
> > wrote:
> > 
> > 
> > Hmmm.  I tried an ALL (a.k.a ANY) instead and I think it works.
> >  But there is a bug in the UI.
> > 
> > 
> > This is what I tried:
> > 
> > <Screen Shot 2021-07-01 at 10.48.15 AM.png>
> > 
> > <Screen Shot 2021-07-01 at 10.50.43 AM.png>
> > 
> > (Two images enclosed)
> > 
> > 
> > But, when I go to edit this rule the Destination Firewall changes
> > from ALL to GREEN.  So I thought it wasn’t accepted.
> > 
> > <Screen Shot 2021-07-01 at 10.52.05 AM.png>
> > 
> > (One more image enclosed)
> > 
> > 
> > Jon
> > 
> > 
> > 
> > > On Jul 1, 2021, at 10:24 AM, Michael Tremer
> > > <michael.tremer(a)ipfire.org> wrote:
> > > 
> > > @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 <jcmurphy26(a)gmail.com>
> > > > 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
> > > > > <michael.tremer(a)ipfire.org> wrote:
> > > > > 
> > > > > Hey Jon,
> > > > > 
> > > > > You probably want “any” as destination.
> > > > > 
> > > > > -Michael
> > > > > 
> > > > > > On 1 Jul 2021, at 04:08, Jon Murphy <jcmurphy26(a)gmail.com>
> > > > > > 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:
> > > > > > 
> > > > > > 
> > > > > > <Screen Shot 2021-06-30 at 9.53.52 PM.png>
> > > > > > 
> > > > > > <Screen Shot 2021-06-30 at 9.53.10 PM.png>
> > > > > > 
> > > > > > 
> > > > > > 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
> > > > > > > <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_ADDRES
> > > > > > > > > > > S'}))  {
> > > > > > > > > > > +                       $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($redirectsf
> > > > > > > > > > > ile,
> > > > > > > > > > > \%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($redirects
> > > > > > > > > > > file,
> > > > > > > > > > > \%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($redirectsf
> > > > > > > > > > > ile,
> > > > > > > > > > > \%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($redirects
> > > > > > > > > > > file,
> > > > > > > > > > > \%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&nbsp;</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_C
> > > > > > > > > > > USTOM_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_DN
> > > > > > > > > > > S_ORANGE'}} =
> > > > > > > > > > > "checked='checked'";
> > > > > > > > > > > +$checked{'REDIR_NTP_ORANGE'}{'off'} = '';
> > > > > > > > > > > +$checked{'REDIR_NTP_ORANGE'}{'on'} = '';
> > > > > > > > > > > +$checked{'REDIR_NTP_ORANGE'}{$settings{'REDIR_NT
> > > > > > > > > > > P_ORANGE'}} =
> > > > > > > > > > > "checked='checked'";
> > > > > > > > > > > +
> > > > > > > > > > > +$selected{'REDIR_ENTRY_INTERFACE'}{$settings{'RE
> > > > > > > > > > > DIR_ENTRY_INTE
> > > > > > > > > > > RFACE'}} = 'selected';
> > > > > > > > > > > +$selected{'REDIR_ENTRY_PROTOCOL'}{$settings{'RED
> > > > > > > > > > > IR_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{'portred
> > > > > > > > > > > ir 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'>&nbsp;</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'>&nbsp;</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) {
> > > > > > > > > > > +
> > > > > > > > > > >                                               $co
> > > > > > > > > > > l="bgcolor='
> > > > > > > > > > > ${Header::colouryellow}'";
> > > > > > > > > > > +                                       } elsif
> > > > > > > > > > > ($key % 2) {
> > > > > > > > > > > +
> > > > > > > > > > >                                               $co
> > > > > > > > > > > l="bgcolor='
> > > > > > > > > > > $color{'color22'}'";
> > > > > > > > > > > +                                       } else {
> > > > > > > > > > > +
> > > > > > > > > > >                                               $co
> > > > > > > > > > > l="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' ) {
> > > > > > > > > > > +
> > > > > > > > > > >                                               $gi
> > > > > > > > > > > f =
> > > > > > > > > > > 'on.gif';
> > > > > > > > > > > +
> > > > > > > > > > >                                               $gd
> > > > > > > > > > > esc =
> > > > > > > > > > > $Lang::tr{'click to disable'};
> > > > > > > > > > > +                                       } else {
> > > > > > > > > > > +
> > > > > > > > > > >                                               $gi
> > > > > > > > > > > f =
> > > > > > > > > > > 'off.gif';
> > > > > > > > > > > +
> > > > > > > > > > >                                               $gd
> > > > > > > > > > > esc =
> > > > > > > > > > > $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>&nbsp;$address</td>
> > > > > > > > > > > +
> > > > > > > > > > >                                               <td
> > > > > > > > > > > width='40%'
> > > > > > > > > > > class='base' align='center'
> > > > > > > > > > > $col>&nbsp;$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>
> > > > > > > > > > > +
> > > > > > > > > > >                                               </t
> > > > > > > > > > > d>
> > > > > > > > > > > +
> > > > > > > > > > >                                               <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>
> > > > > > > > > > > +
> > > > > > > > > > >                                               </t
> > > > > > > > > > > d>
> > > > > > > > > > > +
> > > > > > > > > > >                                               <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>
> > > > > > > > > > > +
> > > > > > > > > > >                                               </t
> > > > > > > > > > > d>
> > > > > > > > > > > +                                       </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>&nbsp</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'>&nbsp;<b>$Lang::tr{'port'}</b></td>
> > > > > > > > > > > +                               <td class='base'
> > > > > > > > > > > width='13%'
> > > > > > > > > > > bgcolor='$color{'color22'}'
> > > > > > > > > > > align='left'>&nbsp;<b>$Lang::tr{'ip
> > > > > > > > > > > address'}</b></td>
> > > > > > > > > > > +                               <td class='base'
> > > > > > > > > > > width='30%'
> > > > > > > > > > > bgcolor='$color{'color22'}'
> > > > > > > > > > > align='left'>&nbsp;<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") {
> > > > > > > > > > > +
> > > > > > > > > > >                                               pri
> > > > > > > > > > > nt "<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") { 
> > > > > > > > > > > +
> > > > > > > > > > >                                               pri
> > > > > > > > > > > nt "<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") { 
> > > > > > > > > > > +
> > > > > > > > > > >                                               pri
> > > > > > > > > > > nt "<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/port
> > > > > > > > > > > redir
> > > > > > > > > > > start");
> > > > > > > > > > > +        } else if (strcmp(argv[1], "stop") == 0)
> > > > > > > > > > > {
> > > > > > > > > > > +
> > > > > > > > > > >                safe_system("/etc/rc.d/init.d/port
> > > > > > > > > > > redir
> > > > > > > > > > > stop");
> > > > > > > > > > > +        } else if (strcmp(argv[1], "restart") ==
> > > > > > > > > > > 0) {
> > > > > > > > > > > +
> > > > > > > > > > >                safe_system("/etc/rc.d/init.d/port
> > > > > > > > > > > redir
> > > > > > > > > > > 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/portr
> > > > > > > > > > > edir 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
> > > > > > > > > > > 
> > > > > > > > > > 
> > > > > > > > > 
> > > > > > > > 
> > > > > > > 
> > > > > > 
> > > > > 
> > > > 
> > > 
> > 
> 


       reply	other threads:[~2021-07-05 12:08 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <6EBF1B5C-79B2-4258-B117-C2A4EB16CCFD@gmail.com>
2021-07-05 12:08 ` Stefan Schantl [this message]
     [not found] <CD95E831-4AE9-40B7-BB91-27B3F3164270@gmail.com>
2021-08-05 20:33 ` Michael Tremer
2021-08-06 15:57   ` 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=4e894b4a343a57c8609665e4f350400e3ec70d15.camel@ipfire.org \
    --to=stefan.schantl@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