public inbox for development@lists.ipfire.org
 help / color / mirror / Atom feed
From: Stefan Schantl <stefan.schantl@ipfire.org>
To: development@lists.ipfire.org
Subject: Re: [PATCH] New addon: Portredirect 1.0
Date: Fri, 06 Aug 2021 17:57:53 +0200	[thread overview]
Message-ID: <c48291dd9864e448ad59c854a884cb85b41dd492.camel@ipfire.org> (raw)
In-Reply-To: <147F4AEF-0264-4B59-AB39-D87B68883D17@ipfire.org>

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

Am Donnerstag, dem 05.08.2021 um 22:33 +0200 schrieb Michael Tremer:
> Hello,
> 
> > On 3 Aug 2021, at 18:04, Jon Murphy <jcmurphy26(a)gmail.com> wrote:
> > 
> > Hello all!
> > 
> > I’m having trouble following the changes to firewall.cgi.  I think
> > there were 4 or 5 patches 
> > submitted to the Dev Mailing List.
> > 
> > Did these get approved?
> 
> That is a good question. AFAIK they are not in c159.
> 
> > 
> > I looked at the Changelog for Core 158 and core 159 (testing) but I
> > didn’t see anything:
> > 
> > https://nightly.ipfire.org/core158/2021-07-21%2015:47:35%20+0000-23498c61/x86_64/changelog.txt
> > 
> > https://nightly.ipfire.org/master/latest/x86_64/changelog.txt
> > 
> > 
> > Can they be added to CU 159?
> > 
> > To be honest I am mainly interested in the DNS redirect (and its
> > cousin NTP redirect).
> > 
> > I’d be happy to help test but I do need some help applying the
> > patches.  
> > Right now I apply them by grabbing a copy of firewall.cgi and
> > manually deleting and then manually adding a patch.
> > Not the smartest way but it works (if I don’t screw-up and make a
> > mistake!).
> 
> @Stefan: What is the status on this?


All firewall related patches, pending on the list, safely can be merged
and tested by a bigger group of testers.

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


  reply	other threads:[~2021-08-06 15:57 UTC|newest]

Thread overview: 9+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <CD95E831-4AE9-40B7-BB91-27B3F3164270@gmail.com>
2021-08-05 20:33 ` Michael Tremer
2021-08-06 15:57   ` Stefan Schantl [this message]
     [not found] <6EBF1B5C-79B2-4258-B117-C2A4EB16CCFD@gmail.com>
2021-07-05 12:08 ` Stefan Schantl
     [not found] <E41194E1-4002-4960-BF73-F57D6BCCD152@gmail.com>
2021-07-05 12:07 ` Stefan Schantl
     [not found] <ADA23788-C972-417C-8F55-DD9D3B335BE9@gmail.com>
2021-07-01 15:24 ` Michael Tremer
     [not found] <A699ABA7-74D3-4551-A981-E2E3A0935F8E@gmail.com>
2021-07-01  8:08 ` Michael Tremer
     [not found] <305D680D-4D10-4D99-9F1D-3589BDF08FA9@gmail.com>
2021-06-28 17:56 ` Michael Tremer
2021-06-27 13:48 Matthias Fischer
2021-06-28 16:04 ` Michael Tremer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=c48291dd9864e448ad59c854a884cb85b41dd492.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