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 </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'> </td></tr>
> > > > > > > > > > > +END
> > > > > > > > > > > +
> > > > > > > > > > > + # create html table with header line 1
> > > > > > > > > > > + print "<table width='80%' cellspacing='0'
> > > > > > > > > > > border='0'><tr>";
> > > > > > > > > > > + print "<th class='base' width='40%'
> > > > > > > > > > > align='left'><b>$Lang::tr{'portredir fw for
> > > > > > > > > > > interface'}</th>";
> > > > > > > > > > > + if ($netsettings{'GREEN_DEV'}) {print
> > > > > > > > > > > "<th
> > > > > > > > > > > class='base' width='10%'><b><font
> > > > > > > > > > > color=green>$Lang::tr{'green'}</font></th>";
> > > > > > > > > > > + } else { print
> > > > > > > > > > > "<th
> > > > > > > > > > > class='base' width='10%'></font></th>"; }
> > > > > > > > > > > + if ($netsettings{'BLUE_DEV'}) {print
> > > > > > > > > > > "<th
> > > > > > > > > > > class='base' width='10%'><b><font
> > > > > > > > > > > color=blue>$Lang::tr{'blue'}</font></th>";
> > > > > > > > > > > + } else { print
> > > > > > > > > > > "<th
> > > > > > > > > > > class='base' width='10%'></font></th>"; }
> > > > > > > > > > > + if ($netsettings{'ORANGE_DEV'}) {print
> > > > > > > > > > > "<th
> > > > > > > > > > > class='base' width='10%'><b><font
> > > > > > > > > > > color=orange>$Lang::tr{'orange'}</font></th>";
> > > > > > > > > > > + } else { print
> > > > > > > > > > > "<th
> > > > > > > > > > > class='base' width='10%'></font></th>"; }
> > > > > > > > > > > +
> > > > > > > > > > > + # the empty right row
> > > > > > > > > > > + print "<th class='base'
> > > > > > > > > > > width='30%'><td></td></th></tr>";
> > > > > > > > > > > +
> > > > > > > > > > > + # line 2
> > > > > > > > > > > + print "<tr><td>$Lang::tr{'portredir force
> > > > > > > > > > > local
> > > > > > > > > > > dns'}</td>";
> > > > > > > > > > > + if ($netsettings{'GREEN_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_DNS_GREEN'
> > > > > > > > > > > $checked{'REDIR_DNS_GREEN'}{'on'}></td>";} else {
> > > > > > > > > > > print
> > > > > > > > > > > "<td></td>";}
> > > > > > > > > > > + if ($netsettings{'BLUE_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_DNS_BLUE'
> > > > > > > > > > > $checked{'REDIR_DNS_BLUE'}{'on'}></td>";}
> > > > > > > > > > > else { print "<td></td>";}
> > > > > > > > > > > + if ($netsettings{'ORANGE_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_DNS_ORANGE'
> > > > > > > > > > > $checked{'REDIR_DNS_ORANGE'}{'on'}></td>";} else
> > > > > > > > > > > { print
> > > > > > > > > > > "<td></td>";}
> > > > > > > > > > > +
> > > > > > > > > > > + # line 3
> > > > > > > > > > > + print "</tr><tr><td>$Lang::tr{'portredir
> > > > > > > > > > > force local
> > > > > > > > > > > ntp'}</td>";
> > > > > > > > > > > + if ($netsettings{'GREEN_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_NTP_GREEN'
> > > > > > > > > > > $checked{'REDIR_NTP_GREEN'}{'on'}></td>";} else {
> > > > > > > > > > > print
> > > > > > > > > > > "<td></td>";}
> > > > > > > > > > > + if ($netsettings{'BLUE_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_NTP_BLUE'
> > > > > > > > > > > $checked{'REDIR_NTP_BLUE'}{'on'}></td>";}
> > > > > > > > > > > else { print "<td></td>";}
> > > > > > > > > > > + if ($netsettings{'ORANGE_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_NTP_ORANGE'
> > > > > > > > > > > $checked{'REDIR_NTP_ORANGE'}{'on'}></td>";} else
> > > > > > > > > > > { print
> > > > > > > > > > > "<td></td>";}
> > > > > > > > > > > +
> > > > > > > > > > > + # line 4
> > > > > > > > > > > + print "</tr><tr><td>$Lang::tr{'portredir
> > > > > > > > > > > enable user
> > > > > > > > > > > redirections'}</td>";
> > > > > > > > > > > + if ($netsettings{'GREEN_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_CUSTOM_GREEN'
> > > > > > > > > > > $checked{'REDIR_CUSTOM_GREEN'}{'on'}></td>";}
> > > > > > > > > > > else { print
> > > > > > > > > > > "<td></td>";}
> > > > > > > > > > > + if ($netsettings{'BLUE_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_CUSTOM_BLUE'
> > > > > > > > > > > $checked{'REDIR_CUSTOM_BLUE'}{'on'}></td>";} else
> > > > > > > > > > > { print
> > > > > > > > > > > "<td></td>";}
> > > > > > > > > > > + if ($netsettings{'ORANGE_DEV'}) {print
> > > > > > > > > > > "<td
> > > > > > > > > > > class='base' align='center'><input
> > > > > > > > > > > type='checkbox'
> > > > > > > > > > > name='REDIR_CUSTOM_ORANGE'
> > > > > > > > > > > $checked{'REDIR_CUSTOM_ORANGE'}{'on'}></td>";}
> > > > > > > > > > > else { print
> > > > > > > > > > > "<td></td>";}
> > > > > > > > > > > +
> > > > > > > > > > > + print <<END;
> > > > > > > > > > > + </tr></table>
> > > > > > > > > > > + <table width='80%' cellspacing='0'
> > > > > > > > > > > border='0'>
> > > > > > > > > > > + <tr><td
> > > > > > > > > > > colspan='2'> </td></tr>
> > > > > > > > > > > + <tr><td
> > > > > > > > > > > align='left'><b>$Lang::tr{'portredir
> > > > > > > > > > > save to activate'}</b></td><td width='5%'
> > > > > > > > > > > align='center'><input
> > > > > > > > > > > type='submit' name='ACTION' value='
> > > > > > > > > > > $Lang::tr{'save'}
> > > > > > > > > > > '></td></tr>
> > > > > > > > > > > + </table></form>
> > > > > > > > > > > +END
> > > > > > > > > > > +
> > > > > > > > > > > +&Header::closebox();
> > > > > > > > > > > +}
> > > > > > > > > > > +
> > > > > > > > > > > +# Function to show elements of the redirects
> > > > > > > > > > > file and allow to
> > > > > > > > > > > add or remove single members of it.
> > > > > > > > > > > +sub showRedirectsBox() {
> > > > > > > > > > > + &Header::openbox('100%', 'center',
> > > > > > > > > > > "$Lang::tr{'portredir custom redirections'}");
> > > > > > > > > > > +
> > > > > > > > > > > + print <<END;
> > > > > > > > > > > + <table width='80%'
> > > > > > > > > > > cellspacing='1' border='0'>
> > > > > > > > > > > + <tr>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > bgcolor='$color{'color20'}'
> > > > > > > > > > > align='center'><b>$Lang::tr{'interface'}</b></td>
> > > > > > > > > > >
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > bgcolor='$color{'color20'}'
> > > > > > > > > > > align='center'><b>$Lang::tr{'protocol'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > bgcolor='$color{'color20'}'
> > > > > > > > > > > align='center'><b>$Lang::tr{'port'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > bgcolor='$color{'color20'}'
> > > > > > > > > > > align='center'><b>$Lang::tr{'ip
> > > > > > > > > > > address'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > bgcolor='$color{'color20'}'
> > > > > > > > > > > align='center'><b>$Lang::tr{'remark'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > colspan='3'
> > > > > > > > > > > bgcolor='$color{'color20'}'></td>
> > > > > > > > > > > + </tr>
> > > > > > > > > > > +END
> > > > > > > > > > > + # Check if some rules
> > > > > > > > > > > have been added
> > > > > > > > > > > to be redirects.
> > > > > > > > > > > + if (keys (%redirects)) {
> > > > > > > > > > > + my $col = "";
> > > > > > > > > > > +
> > > > > > > > > > > + # List all
> > > > > > > > > > > entries of the hash.
> > > > > > > > > > > + foreach my $key
> > > > > > > > > > > (sort keys
> > > > > > > > > > > %redirects){
> > > > > > > > > > > +
> > > > > > > > > > > + # Assign
> > > > > > > > > > > data array
> > > > > > > > > > > positions to some nice variable names.
> > > > > > > > > > > + my
> > > > > > > > > > > $interface =
> > > > > > > > > > > $redirects{$key}[0];
> > > > > > > > > > > + my
> > > > > > > > > > > $protocol =
> > > > > > > > > > > $redirects{$key}[1];
> > > > > > > > > > > + my $port
> > > > > > > > > > > =
> > > > > > > > > > > $redirects{$key}[2];
> > > > > > > > > > > + my
> > > > > > > > > > > $address =
> > > > > > > > > > > $redirects{$key}[3];
> > > > > > > > > > > + my
> > > > > > > > > > > $status =
> > > > > > > > > > > $redirects{$key}[4];
> > > > > > > > > > > + my
> > > > > > > > > > > $remark =
> > > > > > > > > > > $redirects{$key}[5];
> > > > > > > > > > > +
> > > > > > > > > > > + # Check
> > > > > > > > > > > if the key (id)
> > > > > > > > > > > number is even or not.
> > > > > > > > > > > + if
> > > > > > > > > > > ($settings{'ID'} eq
> > > > > > > > > > > $key) {
> > > > > > > > > > > +
> > > > > > > > > > > $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> $address</td>
> > > > > > > > > > > +
> > > > > > > > > > > <td
> > > > > > > > > > > width='40%'
> > > > > > > > > > > class='base' align='center'
> > > > > > > > > > > $col> $remark</td>
> > > > > > > > > > > +
> > > > > > > > > > > <td
> > > > > > > > > > >
> > > > > > > > > > > align='center' $col>
> > > > > > > > > > > +
> > > > > > > > > > >
> > > > > > > > > > > <form
> > > > > > > > > > > method='post' action='$ENV{'SCRIPT_NAME'}'>
> > > > > > > > > > > +
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > <input type='hidden' name='ACTION'
> > > > > > > > > > > value='$Lang::tr{'toggle
> > > > > > > > > > > enable disable'}' />
> > > > > > > > > > > +
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > <input type='image' name='$Lang::tr{'toggle
> > > > > > > > > > > enable disable'}'
> > > > > > > > > > > src='/images/$gif' alt='$gdesc' title='$gdesc' />
> > > > > > > > > > > +
> > > > > > > > > > >
> > > > > > > > > > >
> > > > > > > > > > > <input type='hidden' name='ID' value='$key' />
> > > > > > > > > > > +
> > > > > > > > > > >
> > > > > > > > > > > </form>
> > > > > > > > > > > +
> > > > > > > > > > > </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> </td></tr>\n";
> > > > > > > > > > > + }
> > > > > > > > > > > +
> > > > > > > > > > > + print <<END;
> > > > > > > > > > > + <tr>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='1%'
> > > > > > > > > > > bgcolor='$color{'color22'}'></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='15%'
> > > > > > > > > > > bgcolor='$color{'color22'}'
> > > > > > > > > > > align='left'><b>$Lang::tr{'interface'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='10%'
> > > > > > > > > > > bgcolor='$color{'color22'}'
> > > > > > > > > > > align='left'><b>$Lang::tr{'protocol'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='10%'
> > > > > > > > > > > bgcolor='$color{'color22'}'
> > > > > > > > > > > align='left'> <b>$Lang::tr{'port'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='13%'
> > > > > > > > > > > bgcolor='$color{'color22'}'
> > > > > > > > > > > align='left'> <b>$Lang::tr{'ip
> > > > > > > > > > > address'}</b></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='30%'
> > > > > > > > > > > bgcolor='$color{'color22'}'
> > > > > > > > > > > align='left'> <b>$Lang::tr{'remark'}</b></td
> > > > > > > > > > > >
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='15%'
> > > > > > > > > > > bgcolor='$color{'color22'}'></td>
> > > > > > > > > > > + <td class='base'
> > > > > > > > > > > width='1%'
> > > > > > > > > > > bgcolor='$color{'color22'}'></td>
> > > > > > > > > > > + </tr>
> > > > > > > > > > > +
> > > > > > > > > > > + <form method='post'
> > > > > > > > > > > action='$ENV{'SCRIPT_NAME'}'>
> > > > > > > > > > > + <input type='hidden'
> > > > > > > > > > > name='ID'
> > > > > > > > > > > value='$settings{'ID'}'>
> > > > > > > > > > > + <tr>
> > > > > > > > > > > + <td
> > > > > > > > > > > class='base'></td>
> > > > > > > > > > > + <td><select
> > > > > > > > > > > style='width:90px;'
> > > > > > > > > > > id='interface' name='REDIR_ENTRY_INTERFACE'>
> > > > > > > > > > > +END
> > > > > > > > > > > + if
> > > > > > > > > > > ($netsettings{'GREEN_DEV'})
> > > > > > > > > > > {
> > > > > > > > > > > + if
> > > > > > > > > > > ($entry_interface eq
> > > > > > > > > > > "green") {
> > > > > > > > > > > +
> > > > > > > > > > > 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
> > > > > > > > > > >
> > > > > > > > > >
> > > > > > > > >
> > > > > > > >
> > > > > > >
> > > > > >
> > > > >
> > > >
> > >
> >
>
next parent 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