]> git.gsnw.org Git - m0n0chwall.git/commitdiff
Import m0n0wall 1.0 files.
authormkasper <mkasper@e36fee2c-cc09-0410-a7cc-ebac5c6737de>
Sat, 7 Jan 2006 22:27:43 +0000 (22:27 +0000)
committermkasper <mkasper@e36fee2c-cc09-0410-a7cc-ebac5c6737de>
Sat, 7 Jan 2006 22:27:43 +0000 (22:27 +0000)
git-svn-id: https://svn.m0n0.ch/wall/trunk@2 e36fee2c-cc09-0410-a7cc-ebac5c6737de

119 files changed:
etc/pubkey.pem [new file with mode: 0644]
etc/rc [new file with mode: 0644]
etc/rc.dyndns.storecache [new file with mode: 0644]
etc/rc.firmware [new file with mode: 0644]
etc/rc.initial [new file with mode: 0644]
etc/rc.reboot [new file with mode: 0644]
phpconf/config.xml [new file with mode: 0644]
phpconf/inc/config.inc [new file with mode: 0644]
phpconf/inc/filter.inc [new file with mode: 0644]
phpconf/inc/functions.inc [new file with mode: 0644]
phpconf/inc/globals.inc [new file with mode: 0644]
phpconf/inc/interfaces.inc [new file with mode: 0644]
phpconf/inc/services.inc [new file with mode: 0644]
phpconf/inc/shaper.inc [new file with mode: 0644]
phpconf/inc/system.inc [new file with mode: 0644]
phpconf/inc/util.inc [new file with mode: 0644]
phpconf/inc/vpn.inc [new file with mode: 0644]
phpconf/inc/xmlparse.inc [new file with mode: 0644]
phpconf/rc.banner [new file with mode: 0644]
phpconf/rc.bootup [new file with mode: 0644]
phpconf/rc.initial.defaults [new file with mode: 0644]
phpconf/rc.initial.password [new file with mode: 0644]
phpconf/rc.initial.reboot [new file with mode: 0644]
phpconf/rc.initial.setlanip [new file with mode: 0644]
phpconf/rc.initial.setports [new file with mode: 0644]
phpconf/rc.newwanip [new file with mode: 0644]
webgui/block.gif [new file with mode: 0644]
webgui/block_d.gif [new file with mode: 0644]
webgui/check.gif [new file with mode: 0644]
webgui/diag_backup.php [new file with mode: 0644]
webgui/diag_defaults.php [new file with mode: 0644]
webgui/diag_dhcp_leases.php [new file with mode: 0644]
webgui/diag_ipsec_sad.php [new file with mode: 0644]
webgui/diag_ipsec_spd.php [new file with mode: 0644]
webgui/diag_logs.php [new file with mode: 0644]
webgui/diag_logs_dhcp.php [new file with mode: 0644]
webgui/diag_logs_filter.php [new file with mode: 0644]
webgui/diag_logs_settings.php [new file with mode: 0644]
webgui/diag_ping.php [new file with mode: 0644]
webgui/diag_resetstate.php [new file with mode: 0644]
webgui/down.gif [new file with mode: 0644]
webgui/down_d.gif [new file with mode: 0644]
webgui/e.gif [new file with mode: 0644]
webgui/err.gif [new file with mode: 0644]
webgui/exclam.gif [new file with mode: 0644]
webgui/exec.php [new file with mode: 0644]
webgui/exec_raw.php [new file with mode: 0644]
webgui/fbegin.inc [new file with mode: 0644]
webgui/fend.inc [new file with mode: 0644]
webgui/firewall_aliases.php [new file with mode: 0644]
webgui/firewall_aliases_edit.php [new file with mode: 0644]
webgui/firewall_nat.php [new file with mode: 0644]
webgui/firewall_nat_1to1.php [new file with mode: 0644]
webgui/firewall_nat_1to1_edit.php [new file with mode: 0644]
webgui/firewall_nat_edit.php [new file with mode: 0644]
webgui/firewall_nat_out.php [new file with mode: 0644]
webgui/firewall_nat_out_edit.php [new file with mode: 0644]
webgui/firewall_nat_server.php [new file with mode: 0644]
webgui/firewall_nat_server_edit.php [new file with mode: 0644]
webgui/firewall_rules.php [new file with mode: 0644]
webgui/firewall_rules_edit.php [new file with mode: 0644]
webgui/firewall_shaper.php [new file with mode: 0644]
webgui/firewall_shaper_edit.php [new file with mode: 0644]
webgui/firewall_shaper_pipes.php [new file with mode: 0644]
webgui/firewall_shaper_pipes_edit.php [new file with mode: 0644]
webgui/firewall_shaper_queues.php [new file with mode: 0644]
webgui/firewall_shaper_queues_edit.php [new file with mode: 0644]
webgui/gui.css [new file with mode: 0644]
webgui/guiconfig.inc [new file with mode: 0644]
webgui/in.gif [new file with mode: 0644]
webgui/index.php [new file with mode: 0644]
webgui/interfaces_assign.php [new file with mode: 0644]
webgui/interfaces_lan.php [new file with mode: 0644]
webgui/interfaces_opt.php [new file with mode: 0644]
webgui/interfaces_wan.php [new file with mode: 0644]
webgui/interfaces_wlan.inc [new file with mode: 0644]
webgui/license.php [new file with mode: 0644]
webgui/log.gif [new file with mode: 0644]
webgui/log_d.gif [new file with mode: 0644]
webgui/log_s.gif [new file with mode: 0644]
webgui/log_s_d.gif [new file with mode: 0644]
webgui/logo.gif [new file with mode: 0644]
webgui/logobig.gif [new file with mode: 0644]
webgui/out.gif [new file with mode: 0644]
webgui/pass.gif [new file with mode: 0644]
webgui/pass_d.gif [new file with mode: 0644]
webgui/plus.gif [new file with mode: 0644]
webgui/reboot.php [new file with mode: 0644]
webgui/reject.gif [new file with mode: 0644]
webgui/reject_d.gif [new file with mode: 0644]
webgui/services_dhcp.php [new file with mode: 0644]
webgui/services_dhcp_edit.php [new file with mode: 0644]
webgui/services_dnsmasq.php [new file with mode: 0644]
webgui/services_dnsmasq_edit.php [new file with mode: 0644]
webgui/services_dyndns.php [new file with mode: 0644]
webgui/services_proxyarp.php [new file with mode: 0644]
webgui/services_proxyarp_edit.php [new file with mode: 0644]
webgui/services_snmp.php [new file with mode: 0644]
webgui/status.php [new file with mode: 0644]
webgui/status_interfaces.php [new file with mode: 0644]
webgui/status_wireless.php [new file with mode: 0644]
webgui/system.php [new file with mode: 0644]
webgui/system_advanced.php [new file with mode: 0644]
webgui/system_firmware.php [new file with mode: 0644]
webgui/system_routes.php [new file with mode: 0644]
webgui/system_routes_edit.php [new file with mode: 0644]
webgui/tri_c.gif [new file with mode: 0644]
webgui/tri_o.gif [new file with mode: 0644]
webgui/up.gif [new file with mode: 0644]
webgui/up_d.gif [new file with mode: 0644]
webgui/vpn_ipsec.php [new file with mode: 0644]
webgui/vpn_ipsec_edit.php [new file with mode: 0644]
webgui/vpn_ipsec_keys.php [new file with mode: 0644]
webgui/vpn_ipsec_keys_edit.php [new file with mode: 0644]
webgui/vpn_ipsec_mobile.php [new file with mode: 0644]
webgui/vpn_pptp.php [new file with mode: 0644]
webgui/vpn_pptp_users.php [new file with mode: 0644]
webgui/vpn_pptp_users_edit.php [new file with mode: 0644]
webgui/x.gif [new file with mode: 0644]

diff --git a/etc/pubkey.pem b/etc/pubkey.pem
new file mode 100644 (file)
index 0000000..f935cb5
--- /dev/null
@@ -0,0 +1,6 @@
+-----BEGIN PUBLIC KEY-----
+MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDH/03JimtLfN8ggkf26hOCdAaE
+5Ha+c9cqoms2/AXPMWjapkalizztGhvffTk5v1Y/mDwgkI09kqArnXqRCGFSyRDB
+utGizQ4OghmsBgWzBKw/biLiXZcfXpaZxfAsJ2aSDOy+ezIoPblRfqnVBzg49RPM
+Pe9HoJqCn1GxIhHrKwIDAQAB
+-----END PUBLIC KEY-----
diff --git a/etc/rc b/etc/rc
new file mode 100644 (file)
index 0000000..ced2cf7
--- /dev/null
+++ b/etc/rc
@@ -0,0 +1,46 @@
+#!/bin/sh
+
+# /etc/rc
+# part of m0n0wall (http://neon1.net/m0n0wall)
+#
+# Copyright (C) 2003 Manuel Kasper <mk@neon1.net>.
+# All rights reserved.
+
+stty status '^T'
+
+trap : 2
+trap : 3
+
+HOME=/
+PATH=/sbin:/bin:/usr/sbin:/usr/bin
+export HOME PATH
+
+set -T
+trap "echo 'Reboot interrupted'; exit 1" 3
+
+# make some directories in /var
+mkdir /var/run /var/log /var/etc /var/db
+
+# generate circular logfiles
+clog -i -s 262144 /var/log/system.log
+clog -i -s 262144 /var/log/filter.log
+clog -i -s 32768 /var/log/dhcpd.log
+chmod 0600 /var/log/system.log /var/log/filter.log /var/log/dhcpd.log
+
+adjkerntz -i
+
+# Create an initial utmp file
+cd /var/run && cp /dev/null utmp && chmod 644 utmp
+
+# Build devices database
+dev_mkdb
+
+# Run ldconfig
+/sbin/ldconfig -elf /usr/lib
+
+# let the PHP-based configuration subsystem set up the system now
+/etc/rc.bootup
+
+/etc/rc.banner
+
+exit 0
diff --git a/etc/rc.dyndns.storecache b/etc/rc.dyndns.storecache
new file mode 100644 (file)
index 0000000..180662e
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+# copy cache file to /conf for permanent storage
+/sbin/umount -f /cf
+/sbin/mount -w -o noatime /cf
+/bin/cp /var/db/ez-ipupdate.cache /conf
+/sbin/umount -f /cf
+/sbin/mount -r /cf
diff --git a/etc/rc.firmware b/etc/rc.firmware
new file mode 100644 (file)
index 0000000..56fc7a4
--- /dev/null
@@ -0,0 +1,55 @@
+#!/bin/sh
+
+# /etc/rc.firmware
+# part of m0n0wall (http://neon1.net/m0n0wall)
+#
+# Copyright (C) 2003 Manuel Kasper <mk@neon1.net>.
+# All rights reserved.
+
+CFDEVICE=`cat /var/etc/cfdevice`
+
+if [ $1 != "upgrade" ]; then
+       /sbin/umount -f /ftmp > /dev/null 2>&1
+fi
+
+case $1 in
+enable)
+       /sbin/mount_mfs -s 15360 -T qp120at -b 8192 -f 1024 dummy /ftmp \
+               > /dev/null 2>&1
+       ;;
+upgrade)
+       # wait 5 seconds before beginning
+       sleep 5
+
+       exec </dev/console >/dev/console 2>/dev/console
+
+       echo
+       echo "Firmware upgrade in progress..."
+
+       # backup config
+       mkdir /tmp/configbak
+       cp -p /conf/* /tmp/configbak
+
+       # unmount /cf
+       /sbin/umount -f /cf
+
+       # dd image onto card
+       if [ -r $2 ]; then
+               /usr/bin/gunzip -S "" -c $2 | dd of=/dev/r$CFDEVICE bs=16k > /dev/null 2>&1
+               echo "Image installed."
+       fi
+
+       # mount /cf
+       /sbin/mount -w -o noatime /cf
+
+       # restore config
+       cp -p /tmp/configbak/* /conf
+
+       # remount /cf ro
+       /sbin/umount -f /cf
+       /sbin/mount -r /cf
+
+       echo "Done - rebooting system..."       
+       /sbin/reboot
+       ;;
+esac
diff --git a/etc/rc.initial b/etc/rc.initial
new file mode 100644 (file)
index 0000000..d1fe44a
--- /dev/null
@@ -0,0 +1,69 @@
+#!/bin/sh
+
+# /etc/rc.initial
+# part of m0n0wall (http://neon1.net/m0n0wall)
+#
+# Copyright (C) 2003 Manuel Kasper <mk@neon1.net>.
+# All rights reserved.
+
+# make sure the user can't kill us by pressing Ctrl-C
+trap : 2
+trap : 3
+
+# redirect input/output
+exec </dev/console >/dev/console 2>/dev/console
+
+if [ -r /var/etc/disableconsole ]; then
+
+while : ; do
+
+echo
+echo
+echo "*** Console menu disabled. ***"
+echo
+
+read tmp
+
+done
+
+else 
+
+# endless loop
+while : ; do
+
+# display a cheap menu
+echo
+echo
+echo "m0n0wall console setup"
+echo "**********************"
+echo "1) Interfaces: assign network ports"
+echo "2) Set up LAN IP address"
+echo "3) Reset webGUI password"
+echo "4) Reset to factory defaults"
+echo "5) Reboot system"
+echo
+
+read -p "Enter a number: " opmode
+
+# see what the user has chosen
+case ${opmode} in
+1)
+       /etc/rc.initial.setports
+       ;;
+2)
+       /etc/rc.initial.setlanip
+       ;;
+3)
+       /etc/rc.initial.password
+       ;;
+4)
+       /etc/rc.initial.defaults
+       ;;
+5)
+       /etc/rc.initial.reboot
+       ;;
+esac
+
+done
+
+fi
diff --git a/etc/rc.reboot b/etc/rc.reboot
new file mode 100644 (file)
index 0000000..228d24f
--- /dev/null
@@ -0,0 +1,4 @@
+#!/bin/sh
+
+sleep 5
+/sbin/reboot
diff --git a/phpconf/config.xml b/phpconf/config.xml
new file mode 100644 (file)
index 0000000..40f58ac
--- /dev/null
@@ -0,0 +1,396 @@
+<?xml version="1.0"?>
+<!-- m0n0wall default system configuration -->
+<m0n0wall>
+       <version>1.4</version>
+       <system>
+               <hostname>m0n0wall</hostname>
+               <domain>local</domain>
+               <dnsserver></dnsserver>
+               <dnsallowoverride/>
+               <username>admin</username>
+               <password>$1$2xGLA75j$W/jiJc00HYBZX7kFjxjQv0</password>
+               <timezone>Etc/UTC</timezone>
+               <time-update-interval>300</time-update-interval>
+               <timeservers>pool.ntp.org</timeservers>
+               <webgui>
+                       <protocol>http</protocol>
+                       <!--
+                       <port></port>
+                       <certificate></certificate>
+                       <private-key></private-key>
+                       <noassigninterfaces/>
+                       -->
+               </webgui>
+               <!-- <disableconsolemenu/> -->
+               <!-- <shellcmd></shellcmd> -->
+       </system>
+       <interfaces>
+               <lan>
+                       <if>sis0</if>
+                       <ipaddr>192.168.1.1</ipaddr>
+                       <subnet>24</subnet>
+                       <!--
+                       <wireless>
+                               *see below (opt[n])*
+                       </wireless>
+                       -->
+               </lan>
+               <wan>
+                       <if>sis1</if>
+                       <ipaddr>dhcp</ipaddr>
+                       <!-- *or* ipv4-address *or* 'pppoe' *or* 'pptp' -->
+                       <subnet></subnet>
+                       <gateway></gateway>
+                       <blockpriv/>
+                       <dhcphostname></dhcphostname>
+                       <!--
+                       <wireless>
+                               *see below (opt[n])*
+                       </wireless>
+                       -->
+               </wan>
+               <!--
+               <opt[n]>
+                       <enable/>
+                       <descr></descr>
+                       <if></if>
+                       <ipaddr></ipaddr>
+                       <subnet></subnet>
+                       <bridge>lan|wan|opt[n]</bridge>
+                       <wireless>
+                               <mode>hostap *or* bss *or* ibss</mode>
+                               <ssid></ssid>
+                               <channel></channel>
+                               <wep>
+                                       <enable/>
+                                       <key>
+                                               <txkey/>
+                                               <value></value>
+                                       </key>
+                               </wep>
+                       </wireless>
+               </opt[n]>
+               -->
+       </interfaces>
+       <staticroutes>
+               <!--
+               <route>
+                       <interface>lan|opt[n]|pptp</interface>
+                       <network>xxx.xxx.xxx.xxx/xx</network>
+                       <gateway>xxx.xxx.xxx.xxx</gateway>
+                       <descr></descr>
+               </route>
+               -->
+       </staticroutes>
+       <pppoe>
+               <username></username>
+               <password></password>
+               <provider></provider>
+       </pppoe>
+       <pptp>
+               <username></username>
+               <password></password>
+               <local></local>
+               <subnet></subnet>
+               <remote></remote>
+       </pptp>
+       <dyndns>
+               <!-- <enable/> -->
+               <type>dyndns</type>
+               <username></username>
+               <password></password>
+               <host></host>
+               <mx></mx>
+               <!-- <wildcard/> -->
+       </dyndns>
+       <dhcpd>
+               <lan>
+                       <enable/>
+                       <range>
+                               <from>192.168.1.100</from>
+                               <to>192.168.1.199</to>
+                       </range>
+                       <!--
+                       <winsserver>xxx.xxx.xxx.xxx</winsserver>
+                       <defaultleasetime></defaultleasetime>
+                       <maxleasetime></maxleasetime>
+                       -->
+               </lan>
+               <!--
+               <opt[n]>
+                       ...
+               </opt[n]>
+               -->
+               <!--
+               <staticmap>
+                       <mac>xx:xx:xx:xx:xx:xx</mac>
+                       <ipaddr>xxx.xxx.xxx.xxx</ipaddr>
+                       <descr></descr>
+               </staticmap>
+               -->
+       </dhcpd>
+       <pptpd>
+               <mode><!-- off *or* server *or* redir --></mode>
+               <redir></redir>
+               <localip></localip>
+               <remoteip></remoteip>
+               <!--
+               <user>
+                       <name></name>
+                       <password></password>
+               </user>
+               -->
+       </pptpd>
+       <dnsmasq>
+               <enable/>
+               <!--
+               <hosts>
+                       <host></host>
+                       <domain></domain>
+                       <ip></ip>
+                       <descr></descr>
+               </hosts>
+               -->
+       </dnsmasq>
+       <snmpd>
+               <!-- <enable/> -->
+               <syslocation></syslocation>
+               <syscontact></syscontact>
+               <rocommunity>public</rocommunity>
+       </snmpd>
+       <diag>
+               <ipv6nat>
+                       <!-- <enable/> -->
+                       <ipaddr></ipaddr>
+               </ipv6nat>
+       </diag>
+       <bridge>
+               <!-- <filteringbridge/> -->
+       </bridge>
+       <syslog>
+               <!--
+               <reverse/>
+               <enable/>
+               <remoteserver>xxx.xxx.xxx.xxx</remoteserver>
+               <filter/>
+               <dhcp/>
+               <system/>
+               <nologdefaultblock/>
+               -->
+       </syslog>
+       <nat>
+               <!--
+               <rule>
+                       <external-address></external-address>
+                       <protocol></protocol>
+                       <external-port></external-port>
+                       <target></target>
+                       <local-port></local-port>
+                       <descr></descr>
+               </rule>
+               -->
+               <!--
+               <onetoone>
+                       <external>xxx.xxx.xxx.xxx</external>
+                       <internal>xxx.xxx.xxx.xxx</internal>
+                       <subnet></subnet>
+                       <descr></descr>
+               </onetoone>
+               -->
+               <!--
+               <advancedoutbound>
+                       <enable/>
+                       <rule>
+                               <source>
+                                       <network>xxx.xxx.xxx.xxx/xx</network>
+                               </source>
+                               <destination>
+                                       <not/>
+                                       <any/>
+                                       *or*
+                                       <network>xxx.xxx.xxx.xxx/xx</network>
+                               </destination>
+                               <target>xxx.xxx.xxx.xxx</target>
+                               <descr></descr>
+                       </rule>
+               </advancedoutbound>
+               -->
+               <!--
+               <servernat>
+                       <ipaddr></ipaddr>
+                       <descr></descr>
+               </servernat>
+               -->
+       </nat>
+       <filter>
+               <rule>
+                       <type>pass</type>
+                       <descr>Default LAN -&gt; any</descr>
+                       <interface>lan</interface>
+                       <source>
+                               <network>lan</network>
+                       </source>
+                       <destination>
+                               <any/>
+                       </destination>
+               </rule>
+               <!-- rule syntax:
+               <rule>
+                       <disabled/>
+                       <type>pass|block|reject</type>
+                       <descr>...</descr>
+                       <interface>lan|opt[n]|wan|pptp</interface>
+                       <protocol>tcp|udp|tcp/udp|...</protocol>
+                       <source>
+                               <not/>
+                               
+                               <address>xxx.xxx.xxx.xxx(/xx) or alias</address>
+                               *or*
+                               <network>lan|opt[n]|pptp</network>
+                               *or*
+                               <any/>
+                               
+                               <port>a[-b]</port>
+                       </source>
+                       <destination>
+                               *same as for source*
+                       </destination>
+                       <frags/>
+                       <log/>
+               </rule>
+               -->
+       </filter>
+       <shaper>
+               <!-- <enable/> -->
+               <!-- rule syntax:
+               <rule>
+                       <descr></descr>
+                       
+                       <targetpipe>number (zero based)</targetpipe>
+                       *or*
+                       <targetqueue>number (zero based)</targetqueue>
+                       
+                       <interface>lan|wan|opt[n]|pptp</interface>
+                       <protocol>tcp|udp</protocol>
+                       <direction>in|out</direction>
+                       <source>
+                               <not/>
+                               
+                               <address>xxx.xxx.xxx.xxx(/xx)</address>
+                               *or*
+                               <network>lan|opt[n]|pptp</network>
+                               *or*
+                               <any/>
+                               
+                               <port>a[-b]</port>
+                       </source>
+                       <destination>
+                               *same as for source*
+                       </destination>
+                       
+                       <iplen>from[-to]</iplen>
+                       <tcpflags>(!)fin,syn,rst,psh,ack,urg</tcpflags>
+               </rule>
+               <pipe>
+                       <descr></descr>
+                       <bandwidth></bandwidth>
+                       <delay></delay>
+                       <mask>source|destination</mask>
+               </pipe>
+               <queue>
+                       <descr></descr>
+                       <targetpipe>number (zero based)</targetpipe>
+                       <weight></weight>
+                       <mask>source|destination</mask>
+               </queue>
+               -->
+       </shaper>
+       <ipsec>
+               <!-- <enable/> -->
+               <!-- syntax:
+               <tunnel>
+                       <disabled/>
+                       <descr></descr>
+                       <interface>lan|wan|opt[n]</interface>
+                       <local-subnet>
+                               <address>xxx.xxx.xxx.xxx(/xx)</address>
+                               *or*
+                               <network>lan|opt[n]</network>
+                       </local-subnet>
+                       <remote-subnet>xxx.xxx.xxx.xxx/xx</remote-subnet>
+                       <remote-gateway></remote-gateway>
+                       <p1>
+                               <mode></mode>
+                               <myident>
+                                       <myaddress/>
+                                       *or*
+                                       <address>xxx.xxx.xxx.xxx</address>
+                                       *or*
+                                       <fqdn>the.fq.dn</fqdn>
+                               </myident>
+                               <encryption-algorithm></encryption-algorithm>
+                               <hash-algorithm></hash-algorithm>
+                               <dhgroup></dhgroup>
+                               <lifetime></lifetime>
+                               <pre-shared-key></pre-shared-key>
+                       </p1>
+                       <p2>
+                               <protocol></protocol>
+                               <encryption-algorithm-option></encryption-algorithm-option>
+                               <hash-algorithm-option></hash-algorithm-option>
+                               <pfsgroup></pfsgroup>
+                               <lifetime></lifetime>
+                       </p2>
+               </tunnel>
+               <mobileclients>
+                       <enable/>
+                       <p1>
+                               <mode></mode>
+                               <myident>
+                                       <myaddress/>
+                                       *or*
+                                       <address>xxx.xxx.xxx.xxx</address>
+                                       *or*
+                                       <fqdn>the.fq.dn</fqdn>
+                               </myident>
+                               <encryption-algorithm></encryption-algorithm>
+                               <hash-algorithm></hash-algorithm>
+                               <dhgroup></dhgroup>
+                               <lifetime></lifetime>
+                       </p1>
+                       <p2>
+                               <protocol></protocol>
+                               <encryption-algorithm-option></encryption-algorithm-option>
+                               <hash-algorithm-option></hash-algorithm-option>
+                               <pfsgroup></pfsgroup>
+                               <lifetime></lifetime>
+                       </p2>
+               </mobileclients>
+               <mobilekey>
+                       <ident></ident>
+                       <pre-shared-key></pre-shared-key>
+               </mobilekey>
+               -->
+       </ipsec>
+       <aliases>
+               <!--
+               <alias>
+                       <name></name>
+                       <address>xxx.xxx.xxx.xxx(/xx)</address>
+                       <descr></descr>
+               </alias>
+               -->
+       </aliases>
+       <proxyarp>
+               <!--
+               <proxyarpnet>
+                       <network>xxx.xxx.xxx.xxx/xx</network>
+                       *or*
+                       <range>
+                               <from>xxx.xxx.xxx.xxx</from>
+                               <to>xxx.xxx.xxx.xxx</to>
+                       </range>
+               </proxyarpnet>
+               -->
+       </proxyarp>
+</m0n0wall>
diff --git a/phpconf/inc/config.inc b/phpconf/inc/config.inc
new file mode 100644 (file)
index 0000000..ad3ecc0
--- /dev/null
@@ -0,0 +1,544 @@
+<?php
+/*
+       config.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* include globals/utility/XML parser files */
+require_once("globals.inc");
+require_once("util.inc");
+require_once("xmlparse.inc");
+
+/* read platform */
+if (file_exists("{$g['etc_path']}/platform")) {
+       $g['platform'] = chop(file_get_contents("{$g['etc_path']}/platform"));
+} else {
+       $g['platform'] = "unknown";
+}
+
+if ($g['booting']) {
+       /* find the device where config.xml resides and write out an fstab */
+       unset($cfgdevice);
+       
+       /* check if there's already an fstab (NFS booting?) */
+       if (!file_exists("{$g['etc_path']}/fstab")) {
+       
+               if (strstr($g['platform'], "cdrom")) {
+                       /* config is on floppy disk for CD-ROM version */
+                       $cfgdevice = $cfgpartition = "fd0";
+                       $cfgfstype = "msdos";
+               } else {
+                       /* probe ad0...ad3 until we find the one with config.xml */
+                       for ($cfgn = 0; $cfgn <= 3; $cfgn++) {
+                               if (mwexec("/sbin/mount -r /dev/ad{$cfgn}a {$g['cf_path']}") == 0) {
+                                       if (file_exists("{$g['cf_conf_path']}/config.xml")) {
+                                               /* found it */
+                                               $cfgdevice = "ad" . $cfgn;
+                                               $cfgpartition = $cfgdevice . "a";
+                                               $cfgfstype = "ufs";
+                                               echo "Found configuration on $cfgdevice.\n";
+                                       }
+                                       
+                                       mwexec("/sbin/umount -f {$g['cf_path']}");
+                                       
+                                       if ($cfgdevice)
+                                               break;
+                               }
+                       }
+               }
+               
+               if (!$cfgdevice) {
+                       /* no device found, print an error and die */
+                       echo <<<EOD
+
+
+*******************************************************************************
+* FATAL ERROR                                                                                                                            *
+* The device that contains the configuration file (config.xml) could not be      *
+* found. m0n0wall cannot continue booting.                                                                       *
+*******************************************************************************
+
+
+EOD;
+
+                       mwexec("/sbin/halt");
+                       exit;
+               }
+               
+               /* write device name to a file for rc.firmware */
+               $fd = fopen("{$g['varetc_path']}/cfdevice", "w");
+               fwrite($fd, $cfgdevice . "\n");
+               fclose($fd);
+               
+               /* write out an fstab */
+               $fd = fopen("{$g['etc_path']}/fstab", "w");
+               
+               $fstab = "/dev/{$cfgpartition} {$g['cf_path']} {$cfgfstype} ro 1 1\n";
+               $fstab .= "proc /proc procfs rw 0 0\n";
+               
+               fwrite($fd, $fstab);
+               fclose($fd);
+       }
+       
+       /* mount all filesystems */
+       mwexec("/sbin/mount -a");
+}
+
+/* parse configuration */
+if (!$noparseconfig) {
+       
+       config_lock();
+       
+       /* see if there's a newer cache file */
+       if (file_exists("{$g['tmp_path']}/config.cache") && 
+               (filemtime("{$g['tmp_path']}/config.cache") >= 
+                filemtime("{$g['conf_path']}/config.xml"))) {
+               
+               /* read cache */
+               $config = unserialize(file_get_contents("{$g['tmp_path']}/config.cache"));
+       } else {
+       
+               if (!file_exists("{$g['conf_path']}/config.xml")) {
+                       if ($g['booting']) {
+                               if (strstr($g['platform'], "cdrom")) {
+                                       /* try copying the default config. to the floppy */
+                                       reset_factory_defaults();
+                                       
+                                       echo "No XML configuration file found - using factory defaults.\n"; 
+                                       echo "Make sure that the configuration floppy disk with the conf/config.xml\n";
+                                       echo "file is inserted. If it isn't, your configuration changes will be lost\n";
+                                       echo "on reboot.\n";
+                               } else {
+                                       echo "XML configuration file not found. m0n0wall cannot continue booting.\n"; 
+                                       mwexec("/sbin/halt");
+                                       exit;
+                               }
+                       } else {
+                               config_unlock();
+                               exit(0);
+                       }
+               }
+               
+               $config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
+               
+               if ((float)$config['version'] > (float)$g['latest_config']) {
+                       if ($g['booting']) {
+                               echo <<<EOD
+
+
+*******************************************************************************
+* WARNING!                                                                                                                                       *
+* The current configuration has been created with a newer version of m0n0wall *
+* than this one! This can lead to serious misbehavior and even security                  *
+* holes! You are urged to either upgrade to a newer version of m0n0wall or       *
+* revert to the default configuration immediately!                                                       *
+*******************************************************************************
+
+
+EOD;
+                       }
+               }
+               
+               /* write config cache */
+               $fd = @fopen("{$g['tmp_path']}/config.cache", "wb");
+               if ($fd) {
+                       fwrite($fd, serialize($config));
+                       fclose($fd);
+               }
+       }
+       
+       config_unlock();
+       
+       /* make alias table (for faster lookups) */
+       alias_make_table();
+}
+
+/* mount flash card read/write */
+function conf_mount_rw() {
+       global $g;
+
+       /* don't use mount -u anymore
+          (doesn't sync the files properly and /bin/sync won't help either) */
+       mwexec("/sbin/umount -f {$g['cf_path']}");
+       mwexec("/sbin/mount -w -o noatime {$g['cf_path']}");
+}
+
+/* mount flash card read only */
+function conf_mount_ro() {
+       global $g;
+       
+       mwexec("/sbin/umount -f {$g['cf_path']}");
+       mwexec("/sbin/mount -r {$g['cf_path']}");
+}
+
+/* convert configuration, if necessary */
+function convert_config() {
+       global $config, $g;
+       
+       if ($config['version'] == $g['latest_config'])
+               return;         /* already at latest version */
+       
+       if ($g['booting'])
+               echo "Converting configuration... ";
+       
+       /* convert 1.0 -> 1.1 */
+       if ($config['version'] == "1.0") {
+               $opti = 1;
+               $ifmap = array('lan' => 'lan', 'wan' => 'wan', 'pptp' => 'pptp');
+               
+               /* convert DMZ to optional, if necessary */
+               if (isset($config['interfaces']['dmz'])) {
+                       
+                       $dmzcfg = &$config['interfaces']['dmz'];
+                       
+                       if ($dmzcfg['if']) {
+                               $config['interfaces']['opt' . $opti] = array();
+                               $optcfg = &$config['interfaces']['opt' . $opti];
+                               
+                               $optcfg['enable'] = $dmzcfg['enable'];
+                               $optcfg['descr'] = "DMZ";
+                               $optcfg['if'] = $dmzcfg['if'];
+                               $optcfg['ipaddr'] = $dmzcfg['ipaddr'];
+                               $optcfg['subnet'] = $dmzcfg['subnet'];
+                               
+                               $ifmap['dmz'] = "opt" . $opti;
+                               $opti++;
+                       }
+                       
+                       unset($config['interfaces']['dmz']);
+               }
+               
+               /* convert WLAN1/2 to optional, if necessary */
+               for ($i = 1; isset($config['interfaces']['wlan' . $i]); $i++) {
+                       
+                       if (!$config['interfaces']['wlan' . $i]['if']) {
+                               unset($config['interfaces']['wlan' . $i]);
+                               continue;
+                       }
+                       
+                       $wlancfg = &$config['interfaces']['wlan' . $i];
+                       $config['interfaces']['opt' . $opti] = array();
+                       $optcfg = &$config['interfaces']['opt' . $opti];
+                       
+                       $optcfg['enable'] = $wlancfg['enable'];
+                       $optcfg['descr'] = "WLAN" . $i;
+                       $optcfg['if'] = $wlancfg['if'];
+                       $optcfg['ipaddr'] = $wlancfg['ipaddr'];
+                       $optcfg['subnet'] = $wlancfg['subnet'];
+                       $optcfg['bridge'] = $wlancfg['bridge'];
+                       
+                       $optcfg['wireless'] = array();
+                       $optcfg['wireless']['mode'] = $wlancfg['mode'];
+                       $optcfg['wireless']['ssid'] = $wlancfg['ssid'];
+                       $optcfg['wireless']['channel'] = $wlancfg['channel'];
+                       $optcfg['wireless']['wep'] = $wlancfg['wep'];
+                       
+                       $ifmap['wlan' . $i] = "opt" . $opti;
+                       
+                       unset($config['interfaces']['wlan' . $i]);
+                       $opti++;
+               }
+               
+               /* convert filter rules */
+               $n = count($config['filter']['rule']);
+               for ($i = 0; $i < $n; $i++) {
+               
+                       $fr = &$config['filter']['rule'][$i];
+                       
+                       /* remap interface */
+                       if (array_key_exists($fr['interface'], $ifmap))
+                               $fr['interface'] = $ifmap[$fr['interface']];
+                       else {
+                               /* remove the rule */
+                               echo "\nWarning: filter rule removed " . 
+                                       "(interface '{$fr['interface']}' does not exist anymore).";
+                               unset($config['filter']['rule'][$i]);
+                               continue;
+                       }
+                       
+                       /* remap source network */
+                       if (isset($fr['source']['network'])) {
+                               if (array_key_exists($fr['source']['network'], $ifmap))
+                                       $fr['source']['network'] = $ifmap[$fr['source']['network']];
+                               else {
+                                       /* remove the rule */
+                                       echo "\nWarning: filter rule removed " . 
+                                               "(source network '{$fr['source']['network']}' does not exist anymore).";
+                                       unset($config['filter']['rule'][$i]);
+                                       continue;
+                               }
+                       }
+                                       
+                       /* remap destination network */
+                       if (isset($fr['destination']['network'])) {
+                               if (array_key_exists($fr['destination']['network'], $ifmap))
+                                       $fr['destination']['network'] = $ifmap[$fr['destination']['network']];
+                               else {
+                                       /* remove the rule */
+                                       echo "\nWarning: filter rule removed " . 
+                                               "(destination network '{$fr['destination']['network']}' does not exist anymore).";
+                                       unset($config['filter']['rule'][$i]);
+                                       continue;
+                               }
+                       }
+               }
+               
+               /* convert shaper rules */
+               $n = count($config['shaper']['rule']);
+               if (is_array($config['shaper']['rule']))
+                       for ($i = 0; $i < $n; $i++) {
+               
+                       $fr = &$config['shaper']['rule'][$i];
+                       
+                       /* remap interface */
+                       if (array_key_exists($fr['interface'], $ifmap))
+                               $fr['interface'] = $ifmap[$fr['interface']];
+                       else {
+                               /* remove the rule */
+                               echo "\nWarning: traffic shaper rule removed " . 
+                                       "(interface '{$fr['interface']}' does not exist anymore).";
+                               unset($config['shaper']['rule'][$i]);
+                               continue;
+                       }
+                       
+                       /* remap source network */
+                       if (isset($fr['source']['network'])) {
+                               if (array_key_exists($fr['source']['network'], $ifmap))
+                                       $fr['source']['network'] = $ifmap[$fr['source']['network']];
+                               else {
+                                       /* remove the rule */
+                                       echo "\nWarning: traffic shaper rule removed " . 
+                                               "(source network '{$fr['source']['network']}' does not exist anymore).";
+                                       unset($config['shaper']['rule'][$i]);
+                                       continue;
+                               }
+                       }
+                                       
+                       /* remap destination network */
+                       if (isset($fr['destination']['network'])) {
+                               if (array_key_exists($fr['destination']['network'], $ifmap))
+                                       $fr['destination']['network'] = $ifmap[$fr['destination']['network']];
+                               else {
+                                       /* remove the rule */
+                                       echo "\nWarning: traffic shaper rule removed " . 
+                                               "(destination network '{$fr['destination']['network']}' does not exist anymore).";
+                                       unset($config['shaper']['rule'][$i]);
+                                       continue;
+                               }
+                       }
+               }
+                               
+               $config['version'] = "1.1";
+       }
+       
+       /* convert 1.1 -> 1.2 */
+       if ($config['version'] == "1.1") {
+               /* move LAN DHCP server config */
+               $tmp = $config['dhcpd'];
+               $config['dhcpd'] = array();
+               $config['dhcpd']['lan'] = $tmp;
+               
+               /* encrypt password */
+               $config['system']['password'] = crypt($config['system']['password']);
+               
+               $config['version'] = "1.2";
+       }
+       
+       /* convert 1.2 -> 1.3 */
+       if ($config['version'] == "1.2") {
+               /* convert advanced outbound NAT config */
+               for ($i = 0; isset($config['nat']['advancedoutbound']['rule'][$i]); $i++) {
+                       $curent = &$config['nat']['advancedoutbound']['rule'][$i];
+                       $src = $curent['source'];
+                       $curent['source'] = array();
+                       $curent['source']['network'] = $src;
+                       $curent['destination'] = array();
+                       $curent['destination']['any'] = true;
+               }
+               
+               /* add an explicit type="pass" to all filter rules to make things consistent */
+               for ($i = 0; isset($config['filter']['rule'][$i]); $i++) {
+                       $config['filter']['rule'][$i]['type'] = "pass";
+               }
+               
+               $config['version'] = "1.3";
+       }
+       
+       /* convert 1.3 -> 1.4 */
+       if ($config['version'] == "1.3") {
+               /* convert shaper rules (make pipes) */
+               if (is_array($config['shaper']['rule'])) {
+                       $config['shaper']['pipe'] = array();
+                       
+                       for ($i = 0; isset($config['shaper']['rule'][$i]); $i++) {
+                               $curent = &$config['shaper']['rule'][$i];
+                               
+                               /* make new pipe and associate with this rule */
+                               $newpipe = array();
+                               $newpipe['descr'] = $curent['descr'];
+                               $newpipe['bandwidth'] = $curent['bandwidth'];
+                               $newpipe['delay'] = $curent['delay'];
+                               $newpipe['mask'] = $curent['mask'];
+                               $config['shaper']['pipe'][$i] = $newpipe;
+                               
+                               $curent['targetpipe'] = $i;
+                               
+                               unset($curent['bandwidth']);
+                               unset($curent['delay']);
+                               unset($curent['mask']);
+                       }
+               }
+               
+               $config['version'] = "1.4";
+       }
+       
+       write_config();
+       
+       if ($g['booting'])
+               echo "done\n";
+}
+
+/* save the system configuration */
+function write_config() {
+
+       global $config, $g;
+
+       config_lock();
+
+       conf_mount_rw();
+       
+       /* generate configuration XML */
+       $xmlconfig = dump_xml_config($config, $g['xml_rootobj']);
+       
+       /* write configuration */
+       $fd = fopen("{$g['cf_conf_path']}/config.xml", "w");
+       
+       if (!$fd)
+               die("Unable to open config.xml for writing in write_config()\n");
+               
+       fwrite($fd, $xmlconfig);
+       fclose($fd);
+       
+       conf_mount_ro();
+       
+       /* re-read configuration */
+       $config = parse_xml_config("{$g['conf_path']}/config.xml", $g['xml_rootobj']);
+       
+       /* write config cache */
+       $fd = @fopen("{$g['tmp_path']}/config.cache", "wb");
+       if ($fd) {
+               fwrite($fd, serialize($config));
+               fclose($fd);
+       }
+       
+       config_unlock();
+}
+
+function reset_factory_defaults() {
+       
+       global $g;
+       
+       config_lock();
+       
+       conf_mount_rw();
+       
+       /* create conf directory, if necessary */
+       if (!file_exists("{$g['cf_conf_path']}"))
+               @mkdir("{$g['cf_conf_path']}");
+       
+       /* clear out /conf */
+       $dh = opendir($g['conf_path']); 
+       while ($filename = readdir($dh)) {
+               if (($filename != ".") && ($filename != "..")) { 
+                       unlink($g['conf_path'] . "/" . $filename); 
+               } 
+       }
+       closedir($dh);
+       
+       /* copy default configuration */
+       @copy("{$g['conf_default_path']}/config.xml", "{$g['conf_path']}/config.xml");
+       
+       conf_mount_ro();
+       
+       config_unlock();
+       
+       return 0;
+}
+
+function config_install($conffile) {
+
+       global $config, $g;
+       
+       if (!file_exists($conffile))
+               return 1;
+
+       config_lock();
+       conf_mount_rw();
+       
+       copy($conffile, "{$g['conf_path']}/config.xml");
+       
+       conf_mount_ro();
+       config_unlock();
+       
+       return 0;
+}
+
+/* lock configuration file, decide that the lock file is stale after
+   10 seconds */
+function config_lock() {
+       
+       global $g;
+       
+       $lockfile = "{$g['varrun_path']}/config.lock";
+       
+       $n = 0;
+       while ($n < 10) {
+               /* open the lock file in append mode to avoid race condition */
+               if ($fd = @fopen($lockfile, "x")) {
+                       /* succeeded */
+                       fclose($fd);
+                       return;
+               } else {
+                       /* file locked, wait and try again */
+                       sleep(1);
+                       $n++;
+               }
+       }
+}
+
+/* unlock configuration file */
+function config_unlock() {
+       
+       global $g;
+       
+       $lockfile = "{$g['varrun_path']}/config.lock";
+       
+       if (file_exists($lockfile))
+               unlink($lockfile);
+}
+
+?>
diff --git a/phpconf/inc/filter.inc b/phpconf/inc/filter.inc
new file mode 100644 (file)
index 0000000..74e74b8
--- /dev/null
@@ -0,0 +1,767 @@
+<?php
+/*
+       filter.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+       
+/* include all configuration functions */
+require_once("functions.inc");
+       
+function filter_resync() {
+       global $config, $g;
+       
+       mwexec("/sbin/ipf -y");
+}
+
+function filter_ipmon_start() {
+       global $config, $g;
+       
+       mwexec("/sbin/ipmon -sD");
+}
+
+function filter_configure() {
+       global $config, $g;
+       
+       if ($g['booting'])
+               echo "Configuring firewall... ";
+       
+       /* generate ipnat rules */
+       $ipnatrules = filter_nat_rules_generate();
+       
+       /* load ipnat rules */
+       $fd = popen("/sbin/ipnat -C -f - > /dev/null 2>&1", "w");
+       if (!$fd) {
+               printf("Cannot open /sbin/ipnat in filter_configure()\n");
+               return 1;
+       }
+               
+       fwrite($fd, $ipnatrules);
+       pclose($fd);
+       
+       /* generate ipf rules */
+       $ipfrules = filter_rules_generate();
+       
+       $fd = popen("/sbin/ipf -Fa -f - > /dev/null 2>&1", "w");
+       if (!$fd) {
+               printf("Cannot open /sbin/ipf in filter_configure()\n");
+               return 1;
+       }
+               
+       fwrite($fd, $ipfrules);
+       pclose($fd);
+       
+       if ($g['booting'])
+               echo "done\n";
+       
+       return 0;
+}
+
+function filter_flush_nat_table() {
+       global $config, $g;
+       
+       return mwexec("/sbin/ipnat -F");
+}
+
+function filter_flush_state_table() {
+       global $config, $g;
+       
+       return mwexec("/sbin/ipf -FS");
+}
+
+function filter_nat_rules_generate_if($if, $src, $dst, $target, $mssclamp) {
+
+       if ($target)
+               $tgt = $target . "/32";
+       else
+               $tgt = "0/32";
+
+       $natrule = <<<EOD
+map $if $src $dst -> {$tgt} proxy port ftp ftp/tcp $mssclamp
+map $if $src $dst -> {$tgt} portmap tcp/udp auto $mssclamp
+map $if $src $dst -> {$tgt} $mssclamp
+
+EOD;
+
+       return $natrule;
+}
+
+function filter_nat_rules_generate() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+       $lancfg = $config['interfaces']['lan'];
+       
+       $pptpdcfg = $config['pptpd'];
+       $wanif = get_real_wan_interface();
+       
+       if ($wancfg['mtu'])
+               $mssclamp = "mssclamp " . ($wancfg['mtu'] - 40);
+       else if ($wancfg['ipaddr'] == "pppoe")
+               $mssclamp = "mssclamp 1452";
+       else
+               $mssclamp = "";
+       
+       $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
+       
+       $natrules = "";
+       
+       /* any 1:1 mappings? */
+       if (is_array($config['nat']['onetoone'])) {
+               foreach ($config['nat']['onetoone'] as $natent) {
+                       if (!is_numeric($natent['subnet']))
+                               $sn = 32;
+                       else
+                               $sn = $natent['subnet'];
+                       $natrules .= "bimap {$wanif} {$natent['internal']}/{$sn} -> {$natent['external']}/{$sn}\n";
+               }
+       }
+       
+       /* outbound rules - advanced or standard */
+       if (isset($config['nat']['advancedoutbound']['enable'])) {
+               /* advanced outbound rules */
+               if (is_array($config['nat']['advancedoutbound']['rule'])) {
+                       foreach ($config['nat']['advancedoutbound']['rule'] as $obent) {                                
+                               $dst = "";
+                               $src = "";
+                               if (!isset($obent['destination']['any'])) {
+                                       $src = "from ";
+                                       if (isset($obent['destination']['not'])) 
+                                               $dst = "! to ";
+                                       else
+                                               $dst = "to ";
+                                       $dst .= $obent['destination']['network'];
+                               }
+                               $src .= $obent['source']['network'];
+                               
+                               $natrules .= filter_nat_rules_generate_if($wanif, $src, $dst,
+                                       $obent['target'], $mssclamp);
+                       }
+               }       
+       } else {
+               /* standard outbound rules (one for each interface) */
+               $natrules .= filter_nat_rules_generate_if($wanif,
+                       $lansa . "/" . $lancfg['subnet'], "", null, $mssclamp);
+       
+               /* optional interfaces */
+               for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                       $optcfg = $config['interfaces']['opt' . $i];
+                       
+                       if (isset($optcfg['enable'])) {
+                               $optsa = gen_subnet($optcfg['ipaddr'], $optcfg['subnet']);
+                               $natrules .= filter_nat_rules_generate_if($wanif, 
+                                       $optsa . "/" . $optcfg['subnet'], "", null, $mssclamp);
+                       }
+               }
+       }
+       
+       /* DIAG: add ipv6 NAT, if requested */
+       if (isset($config['diag']['ipv6nat']['enable'])) {
+               $natrules .= "rdr $wanif 0/0 port 0 -> " . 
+               "{$config['diag']['ipv6nat']['ipaddr']} port 0 ipv6\n";
+       }
+       
+       if (isset($config['nat']['rule'])) {
+               foreach ($config['nat']['rule'] as $rule) {
+               
+                       $extport = explode("-", $rule['external-port']);
+                       $target = alias_expand_host($rule['target']);
+                       
+                       if (!$target)
+                               continue;       /* unresolvable alias */
+                       
+                       if ($rule['external-address'])
+                               $extaddr = $rule['external-address'] . "/32";
+                       else
+                               $extaddr = "0/0";
+                       
+                       if ((!$extport[1]) || ($extport[0] == $extport[1])) {
+                               $natrules .=
+                                       "rdr $wanif {$extaddr} port {$extport[0]} -> {$target} " .
+                                       "port {$rule['local-port']} {$rule['protocol']}";
+                       } else {
+                               $natrules .=
+                                       "rdr $wanif {$extaddr} port {$extport[0]}-{$extport[1]} " .
+                                       "-> {$target} " .
+                                       "port {$rule['local-port']} {$rule['protocol']}";
+                       }
+                       
+                       $natrules .= " {$mssclamp}";
+                               
+                       $natrules .= "\n";
+               }
+       }
+       
+       if ($pptpdcfg['mode']) {
+       
+               if ($pptpdcfg['mode'] == "server")
+                       $pptpdtarget = "127.0.0.1";
+               else
+                       $pptpdtarget = $pptpdcfg['redir'];
+       
+               $natrules .= <<<EOD
+
+# PPTP
+rdr $wanif 0/0 port 0 -> $pptpdtarget port 0 gre
+rdr $wanif 0/0 port 1723 -> $pptpdtarget port 1723 tcp {$mssclamp}
+
+EOD;
+       }
+       
+       return $natrules;
+}
+
+function filter_rules_generate() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+       $lancfg = $config['interfaces']['lan'];
+       $pptpdcfg = $config['pptpd'];
+       
+       $lanif = $lancfg['if'];
+       $wanif = get_real_wan_interface();
+       
+       /* rule groups (optional interfaces: see below) */
+       $ifgroups = array("lan" => 100, "wan" => 200);
+       
+       $lanip = $lancfg['ipaddr'];
+       $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
+       $lansn = $lancfg['subnet'];
+       
+       /* optional interfaces */
+       $optcfg = array();
+       
+       for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+               $oc = $config['interfaces']['opt' . $i];
+               
+               if (isset($oc['enable']) && $oc['if']) {
+                       $oic = array();
+                       $oic['if'] = $oc['if'];
+                       
+                       if ($oc['bridge']) {
+                               $oic['ip'] = $config['interfaces'][$oc['bridge']]['ipaddr'];
+                               $oic['sn'] = $config['interfaces'][$oc['bridge']]['subnet'];
+                               $oic['bridge'] = 1;
+                       } else {
+                               $oic['ip'] = $oc['ipaddr'];
+                               $oic['sn'] = $oc['subnet'];
+                       }
+                       
+                       $oic['sa'] = gen_subnet($oic['ip'], $oic['sn']);
+                       $optcfg['opt' . $i] = $oic;
+                       $ifgroups['opt' . $i] = ($i * 100) + 200;
+               }
+       }
+       
+       if ($pptpdcfg['mode'] == "server") {
+               $pptpip = $pptpdcfg['localip'];
+               $pptpsa = $pptpdcfg['remoteip'];
+               $pptpsn = $g['pptp_subnet'];
+       }
+       
+       /* default block logging? */
+       if (!isset($config['syslog']['nologdefaultblock']))
+               $log = "log";
+       else
+               $log = "";
+       
+       $ipfrules = <<<EOD
+# loopback
+pass in quick on lo0 all
+pass out quick on lo0 all
+
+# block short packets
+block in $log quick all with short
+
+# block IP options
+block in $log quick all with ipopts
+
+# allow access to DHCP server on LAN
+pass in quick on $lanif proto udp from any port = 68 to 255.255.255.255 port = 67
+pass in quick on $lanif proto udp from any port = 68 to $lanip port = 67
+pass out quick on $lanif proto udp from $lanip port = 67 to any port = 68
+
+EOD;
+
+       /* allow access to DHCP server on optional interfaces */
+       foreach ($optcfg as $on => $oc) {
+               if (isset($config['dhcpd'][$on]['enable'])) {
+                       $ipfrules .= <<<EOD
+
+# allow access to DHCP server on {$on}
+pass in quick on {$oc['if']} proto udp from any port = 68 to 255.255.255.255 port = 67
+pass in quick on {$oc['if']} proto udp from any port = 68 to {$oc['ip']} port = 67
+pass out quick on {$oc['if']} proto udp from {$oc['ip']} port = 67 to any port = 68
+
+EOD;
+               }
+       }
+
+       $ipfrules .= <<<EOD
+
+# WAN spoof check
+block in $log quick on $wanif from $lansa/$lansn to any
+
+EOD;
+
+       foreach ($optcfg as $oc) {
+               if (!$oc['bridge'])
+                       $ipfrules .= "block in $log quick on $wanif from {$oc['sa']}/{$oc['sn']} to any\n";
+       }
+       
+       /* allow PPTP traffic if PPTP client is enabled on WAN */
+       if ($wancfg['ipaddr'] == "pptp") {
+               $ipfrules .= <<<EOD
+
+# allow PPTP client
+pass in quick on {$wancfg['if']} proto gre from any to any
+pass out quick on {$wancfg['if']} proto gre from any to any
+pass in quick on {$wancfg['if']} proto tcp from any port = 1723 to any
+pass out quick on {$wancfg['if']} proto tcp from any to any port = 1723
+
+EOD;
+       }
+
+       $ipfrules .= <<<EOD
+
+# allow our DHCP client out to the WAN
+# XXX - should be more restrictive
+# (not possible at the moment - need 'me' like in ipfw)
+pass out quick on $wanif proto udp from any port = 68 to any port = 67
+block in $log quick on $wanif proto udp from any port = 67 to $lansa/$lansn port = 68
+pass in quick on $wanif proto udp from any port = 67 to any port = 68
+
+# LAN/OPT spoof check (needs to be after DHCP because of broadcast addresses)
+
+EOD;
+
+       /* LAN spoof check */   
+       $ipfrules .= filter_rules_spoofcheck_generate('lan', $lanif, $lansa, $lansn, $log);
+
+       /* OPT spoof check */
+       foreach ($optcfg as $on => $oc) {
+               $ipfrules .= filter_rules_spoofcheck_generate($on, $oc['if'], $oc['sa'], $oc['sn'], $log);
+       }
+       
+       /* block private networks on WAN? */
+       if (isset($config['interfaces']['wan']['blockpriv'])) {
+               $ipfrules .= <<<EOD
+
+# block anything from private networks on WAN interface
+block in $log quick on $wanif from 10.0.0.0/8 to any
+block in $log quick on $wanif from 127.0.0.0/8 to any
+block in $log quick on $wanif from 172.16.0.0/12 to any
+block in $log quick on $wanif from 192.168.0.0/16 to any
+
+EOD;
+       }
+       
+       /* IPsec enabled? */
+       if (isset($config['ipsec']['enable']) && 
+               ((is_array($config['ipsec']['tunnel']) &&
+               count($config['ipsec']['tunnel'])) ||
+                       isset($config['ipsec']['mobileclients']['enable']))) {
+               
+               $curwanip = get_current_wan_address();
+               
+               if ($curwanip)
+                       $ipfrules .= filter_rules_ipsec_generate($wanif, $curwanip);
+               
+               $ipfrules .= filter_rules_ipsec_generate($lanif, $lanip);
+               
+               foreach ($optcfg as $on => $oc) {
+                       $ipfrules .= filter_rules_ipsec_generate($oc['if'], $oc['ip']);
+               }
+       }
+
+       /* XXX - the first section is only needed because ipf refuses to
+               parse rules that have "flags S/SAFR" and proto "tcp/udp" set because
+               UDP does not have flags, but we still want to offer the TCP/UDP protocol
+               option to the user */
+               
+       $ipfrules .= <<<EOD
+
+# Block TCP packets that do not mark the start of a connection
+skip 1 in proto tcp all flags S/SAFR
+block in $log quick proto tcp all
+
+#---------------------------------------------------------------------------
+# group head 100 - LAN interface
+#---------------------------------------------------------------------------
+block in $log quick on $lanif all head 100
+
+# let out anything from the firewall host itself and decrypted IPsec traffic
+pass out quick on $lanif all keep state
+
+#---------------------------------------------------------------------------
+# group head 200 - WAN interface
+#---------------------------------------------------------------------------
+block in $log quick on $wanif all head 200
+
+# let out anything from the firewall host itself and decrypted IPsec traffic
+pass out quick on $wanif all keep state
+
+EOD;
+
+       /* group heads for optional interfaces */
+       foreach ($optcfg as $on => $oc) {
+       
+               $ingroup = $ifgroups[$on];
+       
+               $ipfrules .= <<<EOD
+               
+#---------------------------------------------------------------------------
+# group head {$ingroup} - {$on} interface
+#---------------------------------------------------------------------------
+block in $log quick on {$oc['if']} all head {$ingroup}
+
+# let out anything from the firewall host itself and decrypted IPsec traffic
+pass out quick on {$oc['if']} all keep state
+
+EOD;
+       
+       }
+       
+       $ipfrules .= <<<EOD
+
+# make sure the user cannot lock himself out of the webGUI
+pass in quick from $lansa/$lansn to $lanip keep state group 100
+
+EOD;
+       
+       /* PPTPd enabled? */
+       if ($pptpdcfg['mode'] && ($pptpdcfg['mode'] != "off")) {
+       
+               if ($pptpdcfg['mode'] == "server")
+                       $pptpdtarget = "127.0.0.1";
+               else
+                       $pptpdtarget = $pptpdcfg['redir'];
+                       
+               $ipfrules .= <<<EOD
+
+# PPTP rules
+pass in quick proto gre from any to $pptpdtarget keep state group 200
+pass in quick proto tcp from any to $pptpdtarget port = 1723 keep state group 200
+
+EOD;
+       }
+       
+       $i = 0;
+       
+       $ipfrules .= "\n# User-defined rules follow\n";
+       
+       if (isset($config['filter']['rule']))
+               foreach ($config['filter']['rule'] as $rule) {
+               
+               /* don't include disabled rules */
+               if (isset($rule['disabled'])) {
+                       $i++;
+                       continue;
+               }
+               
+               /* does the rule deal with a PPTP interface? */
+               if ($rule['interface'] == "pptp") {
+               
+                       if ($pptpdcfg['mode'] != "server")
+                               continue;
+                               
+                       $nif = $g['n_pptp_units'];
+                       $ispptp = true;
+               } else {
+                       
+                       if (strstr($rule['interface'], "opt")) {
+                               if (!array_key_exists($rule['interface'], $optcfg))
+                                       continue;
+                       }
+                       
+                       $nif = 1;
+                       $ispptp = false;
+               }
+               
+               if ($pptpdcfg['mode'] != "server") {
+                       if (($rule['source']['network'] == "pptp") ||
+                               ($rule['destination']['network'] == "pptp"))
+                                       continue;
+               }
+               
+               if ($rule['source']['network'] && strstr($rule['source']['network'], "opt")) {
+                       if (!array_key_exists($rule['source']['network'], $optcfg))
+                               continue;
+               }
+               if ($rule['destination']['network'] && strstr($rule['destination']['network'], "opt")) {
+                       if (!array_key_exists($rule['destination']['network'], $optcfg))
+                               continue;
+               }
+               
+               /* check for unresolvable aliases */
+               if ($rule['source']['address'] && !alias_expand($rule['source']['address']))
+                       continue;
+               if ($rule['destination']['address'] && !alias_expand($rule['destination']['address']))
+                       continue;
+               
+               for ($iif = 0; $iif < $nif; $iif++) {
+                       
+                       if (!$ispptp) {
+                       
+                               $groupnum = $ifgroups[$rule['interface']];
+                               
+                               if (!$groupnum) {
+                                       printf("Invalid interface name in rule $i\n");
+                                       break;
+                               }
+                       }
+                       
+                       $type = $rule['type'];
+                       if ($type != "pass" && $type != "block" && $type != "reject") {
+                               /* default (for older rules) is pass */
+                               $type = "pass";
+                       }
+
+                       if ($type == "reject") {
+                               /* special reject packet */
+                               if ($rule['protocol'] == "tcp") {
+                                       $line = "block return-rst";
+                               } else if ($rule['protocol'] == "udp") {
+                                       $line = "block return-icmp";
+                               } else {
+                                       $line = "block";
+                               }
+                       } else {
+                               $line = $type;
+                       }
+                       
+                       $line .= " in ";
+
+                       if (isset($rule['log']))
+                               $line .= "log ";
+
+                       $line .= "quick ";
+                       
+                       if ($ispptp) {
+                               $line .= "on ng" . ($iif+1) . " ";
+                       }
+                       
+                       if (isset($rule['protocol'])) {
+                               $line .= "proto {$rule['protocol']} ";
+                       }
+                       
+                       /* source address */
+                       if (isset($rule['source']['any'])) {
+                               $src = "any";
+                       } else if ($rule['source']['network']) {
+                               
+                               if (strstr($rule['source']['network'], "opt")) {
+                                       $src = $optcfg[$rule['source']['network']]['sa'] . "/" .
+                                               $optcfg[$rule['source']['network']]['sn'];
+                               } else {
+                                       switch ($rule['source']['network']) {
+                                               case 'lan':
+                                                       $src = "$lansa/$lansn";
+                                                       break;
+                                               case 'pptp':
+                                                       $src = "$pptpsa/$pptpsn";
+                                                       break;
+                                       }
+                               }
+                       } else if ($rule['source']['address']) {
+                               $src = alias_expand($rule['source']['address']);
+                       }
+                       
+                       if (!$src) {
+                               printf("No source address found in rule $i\n");
+                               break;
+                       }
+                       
+                       if (isset($rule['source']['not'])) {
+                               $line .= "from !$src ";
+                       } else {
+                               $line .= "from $src ";
+                       }
+                       
+                       if (in_array($rule['protocol'], array("tcp","udp","tcp/udp"))) {
+                               
+                               if ($rule['source']['port']) {
+                                       $srcport = explode("-", $rule['source']['port']);
+                                       
+                                       if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
+                                               $line .= "port = {$srcport[0]} ";
+                                       } else if (($srcport[0] == 1) && ($srcport[1] == 65535)) {
+                                               /* no need for a port statement here */
+                                       } else if ($srcport[1] == 65535) {
+                                               $line .= "port >= {$srcport[0]} "; 
+                                       } else if ($srcport[0] == 1) {
+                                               $line .= "port <= {$srcport[1]} "; 
+                                       } else {
+                                               $srcport[0]--;
+                                               $srcport[1]++;
+                                               $line .= "port {$srcport[0]} >< {$srcport[1]} ";
+                                       }
+                               }
+                       }
+                       
+                       /* destination address */
+                       if (isset($rule['destination']['any'])) {
+                               $dst = "any";
+                       } else if ($rule['destination']['network']) {
+                               
+                               if (strstr($rule['destination']['network'], "opt")) {
+                                       $dst = $optcfg[$rule['destination']['network']]['sa'] . "/" .
+                                               $optcfg[$rule['destination']['network']]['sn'];
+                               } else {
+                                       switch ($rule['destination']['network']) {
+                                               case 'lan':
+                                                       $dst = "$lansa/$lansn";
+                                                       break;
+                                               case 'pptp':
+                                                       $dst = "$pptpsa/$pptpsn";
+                                                       break;
+                                       }
+                               }
+                       } else if ($rule['destination']['address']) {
+                               $dst = alias_expand($rule['destination']['address']);
+                       }
+                       
+                       if (!$dst) {
+                               printf("No destination address found in rule $i\n");
+                               break;
+                       }
+                       
+                       if (isset($rule['destination']['not'])) {
+                               $line .= "to !$dst ";
+                       } else {
+                               $line .= "to $dst ";
+                       }
+                       
+                       if (in_array($rule['protocol'], array("tcp","udp","tcp/udp"))) {
+                               
+                               if ($rule['destination']['port']) {
+                                       $dstport = explode("-", $rule['destination']['port']);
+                                       
+                                       if ((!$dstport[1]) || ($dstport[0] == $dstport[1])) {
+                                               $line .= "port = {$dstport[0]} ";
+                                       } else if (($dstport[0] == 1) && ($dstport[1] == 65535)) {
+                                               /* no need for a port statement here */
+                                       } else if ($dstport[1] == 65535) {
+                                               $line .= "port >= {$dstport[0]} "; 
+                                       } else if ($dstport[0] == 1) {
+                                               $line .= "port <= {$dstport[1]} "; 
+                                       }  else {
+                                               $dstport[0]--;
+                                               $dstport[1]++;
+                                               $line .= "port {$dstport[0]} >< {$dstport[1]} ";
+                                       }
+                               }
+                       }
+                       
+                       if ($type == "pass") {
+                               $line .= "keep state ";
+                       
+                               if (isset($rule['frags']))
+                                       $line .= "keep frags ";
+                       }
+                       
+                       if ($type == "reject" && $rule['protocol'] == "tcp") {
+                               /* special reject packet */
+                               $line .= "flags S/SA ";
+                       }
+                               
+                       if (!$ispptp) {
+                               $line .= "group $groupnum ";
+                       }
+                       
+                       $line .= "\n";
+                       
+                       $ipfrules .= $line;
+               }
+               
+               $i++;
+       }
+       
+       $ipfrules .= <<<EOD
+       
+#---------------------------------------------------------------------------
+# default rules (just to be sure)
+#---------------------------------------------------------------------------
+block in $log quick all
+block out $log quick all
+
+EOD;
+       
+       return $ipfrules;
+}
+
+function filter_rules_spoofcheck_generate($ifname, $if, $sa, $sn, $log) {
+
+       global $g, $config;
+       
+       $ipfrules = "";
+
+       if (is_array($config['staticroutes']['route']) && count($config['staticroutes']['route'])) {
+               /* count rules */
+               $n = 1;
+               foreach ($config['staticroutes']['route'] as $route) {
+                       if ($route['interface'] == $ifname)
+                               $n++;
+               }
+               
+               /* output skip rules */
+               foreach ($config['staticroutes']['route'] as $route) {
+                       if ($route['interface'] == $ifname) {
+                               $ipfrules .= "skip $n in on $if from {$route['network']} to any\n";
+                               $n--;
+                       }
+               }
+               $ipfrules .= "skip 1 in on $if from $sa/$sn to any\n";
+               $ipfrules .= "block in $log quick on $if all\n";
+       } else {
+               $ipfrules .= "block in $log quick on $if from ! $sa/$sn to any\n";
+       }
+       
+       return $ipfrules;
+}
+
+function filter_rules_ipsec_generate($ifname, $ip) {
+
+       $ipfrules = <<<EOD
+
+# Pass IKE packets
+pass in quick on {$ifname} proto udp from any to {$ip} port = 500
+pass out quick on {$ifname} proto udp from {$ip} port = 500 to any
+
+# Pass ESP packets
+pass in quick on {$ifname} proto esp from any to {$ip}
+pass out quick on {$ifname} proto esp from {$ip} to any
+
+# Pass AH packets
+pass in quick on {$ifname} proto ah from any to {$ip}
+pass out quick on {$ifname} proto ah from {$ip} to any
+
+EOD;
+       
+       return $ipfrules;
+}
+
+?>
diff --git a/phpconf/inc/functions.inc b/phpconf/inc/functions.inc
new file mode 100644 (file)
index 0000000..51f02d7
--- /dev/null
@@ -0,0 +1,39 @@
+<?php
+/*
+    functions.inc
+    part of m0n0wall (http://m0n0.ch/wall)
+    
+    Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+    All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+    
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    
+    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* include all configuration functions */
+require_once("system.inc");
+require_once("interfaces.inc");
+require_once("services.inc");
+require_once("filter.inc");
+require_once("shaper.inc");
+require_once("vpn.inc");
+
+?>
diff --git a/phpconf/inc/globals.inc b/phpconf/inc/globals.inc
new file mode 100644 (file)
index 0000000..33d0291
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+/*
+    globals.inc
+    part of m0n0wall (http://m0n0.ch/wall)
+    
+    Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+    All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+    
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    
+    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$g = array(
+    "varrun_path" => "/var/run",
+    "varetc_path" => "/var/etc",
+    "vardb_path" => "/var/db",
+    "etc_path" => "/etc",
+    "tmp_path" => "/tmp",
+    "conf_path" => "/conf",
+    "ftmp_path" => "/ftmp",
+    "conf_default_path" => "/conf.default",
+    "cf_path" => "/cf",
+    "cf_conf_path" => "/cf/conf",
+    "www_path" => "/usr/local/www",
+    "xml_rootobj" => "m0n0wall",
+    "pppoe_interface" => "ng0",
+    "n_pptp_units" => 16,
+    "pptp_subnet" => 28,
+    "debug" => false,
+    "latest_config" => "1.4"
+);
+
+?>
diff --git a/phpconf/inc/interfaces.inc b/phpconf/inc/interfaces.inc
new file mode 100644 (file)
index 0000000..8986d1a
--- /dev/null
@@ -0,0 +1,542 @@
+<?php
+/*
+       interfaces.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* include all configuration functions */
+require_once("functions.inc");
+
+function interfaces_loopback_configure() {
+       global $config, $g;
+
+       mwexec("/sbin/ifconfig lo0 127.0.0.1");
+       
+       return 0;
+}
+
+function interfaces_lan_configure() {
+       global $config, $g;
+       
+       if ($g['booting'])
+               echo "Configuring LAN interface... ";
+       
+       $lancfg = $config['interfaces']['lan'];
+               
+       /* wireless configuration? */
+       if (is_array($lancfg['wireless']))
+               interfaces_wireless_configure($lancfg['if'], $lancfg['wireless']);
+       
+       /* MAC spoofing? */
+       if ($lancfg['spoofmac'])
+               mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) . 
+                       " link " . escapeshellarg($lancfg['spoofmac']));
+       
+       mwexec("/sbin/ifconfig " . escapeshellarg($lancfg['if']) . " " . 
+               escapeshellarg($lancfg['ipaddr'] . "/" . $lancfg['subnet']));
+       
+       if (!$g['booting']) {
+               /* make new hosts file */
+               system_hosts_generate();
+               
+               /* reconfigure static routes (kernel may have deleted them) */
+               system_routing_configure();
+               
+               /* reload ipfilter (address may have changed) */
+               filter_configure();
+               
+               /* reload shaper (subnet may have changed) */
+               shaper_configure();
+               
+               /* reload IPsec tunnels */
+               vpn_ipsec_configure();
+               
+               /* reload dhcpd (gateway may have changed) */
+               services_dhcpd_configure();
+               
+               /* reload dnsmasq */
+               services_dnsmasq_configure();
+               
+               /* reload webgui */
+               system_webgui_start();
+       }
+       
+       if ($g['booting'])
+               echo "done\n";
+       
+       return 0;
+}
+
+function interfaces_optional_configure() {
+       global $config, $g;
+       global $bridgeconfig;
+       
+       /* Reset bridge configuration.  Interfaces will add to it. */
+       $bridgeconfig = "";
+       
+       for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+               interfaces_optional_configure_if($i);
+       }
+       
+       if ($bridgeconfig) {
+               /* Set the system bridge configuration and enable bridging. */
+               mwexec("/sbin/sysctl net.link.ether.bridge_cfg=" . $bridgeconfig);
+               
+               if (isset($config['bridge']['filteringbridge']))
+                       mwexec("/sbin/sysctl net.link.ether.bridge_ipf=1");
+               
+               mwexec("/sbin/sysctl net.link.ether.bridge=1");
+       } else {
+               mwexec("/sbin/sysctl net.link.ether.bridge_ipf=0");
+               mwexec("/sbin/sysctl net.link.ether.bridge=0");
+       }
+       
+       if (!$g['booting']) {
+               /* reconfigure static routes (kernel may have deleted them) */
+               system_routing_configure();
+               
+               /* reload ipfilter (address may have changed) */
+               filter_configure();
+               
+               /* reload shaper (address may have changed) */
+               shaper_configure();
+               
+               /* reload IPsec tunnels */
+               vpn_ipsec_configure();
+               
+               /* reload dhcpd (interface enabled/disabled/bridged status may have changed) */
+               services_dhcpd_configure();
+               
+               /* restart dnsmasq */
+               services_dnsmasq_configure();
+       }
+       
+       return 0;
+}
+
+function interfaces_optional_configure_if($opti) {
+       global $config, $g;
+       global $bridgeconfig;
+       
+       $optcfg = $config['interfaces']['opt' . $opti];
+       
+       if ($g['booting']) {
+               $optdescr = "";
+               if ($optcfg['descr'])
+                       $optdescr = " ({$optcfg['descr']})";
+               echo "Configuring OPT{$opti}{$optdescr} interface... ";
+       }
+       
+       if (isset($optcfg['enable'])) {
+               /* wireless configuration? */
+               if (is_array($optcfg['wireless']))
+                       interfaces_wireless_configure($optcfg['if'], $optcfg['wireless']);
+               
+               /* MAC spoofing? */
+               if ($optcfg['spoofmac'])
+                       mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . 
+                               " link " . escapeshellarg($optcfg['spoofmac']));
+               
+               /* bridged? */
+               if ($optcfg['bridge']) {
+                       mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . 
+                               " delete up");
+                       
+                       if ($bridgeconfig != "")
+                               $bridgeconfig .= ",";
+                       
+                       $bridgeconfig .= $optcfg['if'] . ":" . $opti . "," .
+                               $config['interfaces'][$optcfg['bridge']]['if'] .
+                               ":" . $opti;
+               } else {
+                       mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . " " . 
+                               escapeshellarg($optcfg['ipaddr'] . "/" . $optcfg['subnet']));
+               }
+       } else {
+               mwexec("/sbin/ifconfig " . escapeshellarg($optcfg['if']) . 
+                       " delete down");
+       }
+       
+       if ($g['booting'])
+               echo "done\n";
+       
+       return 0;
+}
+
+function interfaces_wireless_configure($if, $wlcfg) {
+       global $config, $g;
+       
+       /* wireless configuration */
+       $ifcargs = escapeshellarg($if) . 
+               " ssid " . escapeshellarg($wlcfg['ssid']) . " channel " . 
+               escapeshellarg($wlcfg['channel']) . " ";
+       
+       if ($wlcfg['stationname'])
+               $ifcargs .= "stationname " . escapeshellarg($wlcfg['stationname']) . " ";
+       
+       if (isset($wlcfg['wep']['enable']) && is_array($wlcfg['wep']['key'])) {
+               $ifcargs .= "wepmode on ";
+               
+               $i = 1;
+               foreach ($wlcfg['wep']['key'] as $wepkey) {
+                       $ifcargs .= "wepkey " . escapeshellarg("{$i}:{$wepkey['value']}") . " ";
+                       if (isset($wepkey['txkey'])) {
+                               $ifcargs .= "weptxkey {$i} ";
+                       }
+                       $i++;
+               }
+       } else {
+               $ifcargs .= "wepmode off ";
+       }
+       
+       switch ($wlcfg['mode']) {
+               case 'hostap':
+                       if (strstr($if, "wi"))
+                               $ifcargs .= "-mediaopt ibss mediaopt hostap ";
+                       break;
+               case 'ibss':
+               case 'IBSS':
+                       if (strstr($if, "wi"))
+                               $ifcargs .= "-mediaopt hostap mediaopt ibss ";
+                       else if (strstr($if, "an"))
+                               $ifcargs .= "mediaopt adhoc ";
+                       break;
+               case 'bss':
+               case 'BSS':
+                       if (strstr($if, "wi"))
+                               $ifcargs .= "-mediaopt hostap -mediaopt ibss ";
+                       else if (strstr($if, "an"))
+                               $ifcargs .= "-mediaopt adhoc ";
+                       break;
+       }
+       
+       $ifcargs .= "up";
+       
+       mwexec("/sbin/ifconfig " . $ifcargs);
+       
+       return 0;
+}
+
+function interfaces_wan_configure() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+       
+       if ($g['booting'])
+               echo "Configuring WAN interface... ";
+       else {
+               /* kill dhclient */
+               killbypid("{$g['varrun_path']}/dhclient.pid");
+               
+               /* kill PPPoE client (mpd) */
+               killbypid("{$g['varrun_path']}/mpd.pid");
+               
+               /* wait for processes to die */
+               sleep(2);
+               
+               /* remove dhclient.conf, if it exists */
+               if (file_exists("{$g['varetc_path']}/dhclient.conf")) {
+                       unlink("{$g['varetc_path']}/dhclient.conf");
+               }
+               /* remove mpd.conf, if it exists */
+               if (file_exists("{$g['varetc_path']}/mpd.conf")) {
+                       unlink("{$g['varetc_path']}/mpd.conf");
+               }
+               /* remove mpd.links, if it exists */
+               if (file_exists("{$g['varetc_path']}/mpd.links")) {
+                       unlink("{$g['varetc_path']}/mpd.links");
+               }
+       }
+       
+       /* remove all addresses first */
+       while (mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " -alias") == 0);
+       mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " down");
+               
+       /* wireless configuration? */
+       if (is_array($wancfg['wireless']))
+               interfaces_wireless_configure($wancfg['if'], $wancfg['wireless']);
+       
+       if ($wancfg['spoofmac'])
+               mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . 
+                       " link " . escapeshellarg($wancfg['spoofmac']));
+       
+       switch ($wancfg['ipaddr']) {
+       
+               case 'dhcp':
+                       interfaces_wan_dhcp_configure();
+                       break;
+                       
+               case 'pppoe':
+                       interfaces_wan_pppoe_configure();
+                       break;
+                       
+               case 'pptp':
+                       interfaces_wan_pptp_configure();
+                       break;
+                       
+               default:
+                       mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " . 
+                               escapeshellarg($wancfg['ipaddr'] . "/" . $wancfg['subnet']));
+                       
+                       /* install default route */
+                       mwexec("/sbin/route delete default");
+                       mwexec("/sbin/route add default " . escapeshellarg($wancfg['gateway']));
+                       
+                       /* resync ipfilter (done automatically for DHCP/PPPoE/PPTP) */
+                       filter_resync();
+       }
+       
+       if (!$g['booting']) {
+               /* reconfigure static routes (kernel may have deleted them) */
+               system_routing_configure();
+               
+               /* reload ipfilter */
+               filter_configure();
+               
+               /* reload shaper */
+               shaper_configure();
+               
+               /* reload ipsec tunnels */
+               vpn_ipsec_configure();
+               
+               /* restart ez-ipupdate */
+               services_dyndns_configure();
+               
+               /* restart dnsmasq */
+               services_dnsmasq_configure();
+       }
+       
+       if ($g['booting'])
+               echo "done\n";
+       
+       return 0;
+}
+
+function interfaces_wan_dhcp_configure() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+
+       /* generate dhclient.conf */
+       $fd = fopen("{$g['varetc_path']}/dhclient.conf", "w");
+       if (!$fd) {
+               printf("Error: cannot open dhclient.conf in interfaces_wan_dhcp_configure().\n");
+               return 1;
+       }
+       $dhclientconf = "";
+       if ($wancfg['dhcphostname']) {
+               $dhclientconf .= <<<EOD
+send dhcp-client-identifier "{$wancfg['dhcphostname']}";
+interface "{$wancfg['if']}" {
+       send host-name "{$wancfg['dhcphostname']}";
+}
+
+EOD;
+       }
+
+       fwrite($fd, $dhclientconf);
+       fclose($fd);
+       
+       /* fire up dhclient - don't wait for the lease (-nw) */
+       mwexec("/sbin/dhclient -nw -cf {$g['varetc_path']}/dhclient.conf " .
+               escapeshellarg($wancfg['if']));
+       
+       return 0;
+}
+
+function interfaces_wan_pppoe_configure() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+       $pppoecfg = $config['pppoe'];
+       
+       /* generate mpd.conf */
+       $fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
+       if (!$fd) {
+               printf("Error: cannot open mpd.conf in interfaces_wan_pppoe_configure().\n");
+               return 1;
+       }
+               
+       $mpdconf = <<<EOD
+pppoe:
+       new -i ng0 pppoe pppoe
+       set iface route default
+       set iface disable on-demand
+       set iface idle 0
+       set iface up-script /usr/local/sbin/ppp-linkup
+       set bundle disable multilink
+       set bundle authname "{$pppoecfg['username']}"
+       set bundle password "{$pppoecfg['password']}"
+       set link keep-alive 10 60
+       set link max-redial 0
+       set link no acfcomp protocomp
+       set link disable pap chap
+       set link accept chap
+       set link mtu 1492
+       set ipcp yes vjcomp
+       set ipcp ranges 0.0.0.0/0 0.0.0.0/0
+       open iface
+       
+EOD;
+
+       fwrite($fd, $mpdconf);
+       fclose($fd);
+       
+       /* generate mpd.links */
+       $fd = fopen("{$g['varetc_path']}/mpd.links", "w");
+       if (!$fd) {
+               printf("Error: cannot open mpd.links in interfaces_wan_pppoe_configure().\n");
+               return 1;
+       }
+               
+       $mpdconf = <<<EOD
+pppoe:
+       set link type pppoe
+       set pppoe iface {$wancfg['if']}
+       set pppoe service "{$pppoecfg['provider']}"
+       
+EOD;
+
+       fwrite($fd, $mpdconf);
+       fclose($fd);
+       
+       /* fire up mpd */
+       mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpd.pid pppoe");
+       
+       return 0;
+}
+
+function interfaces_wan_pptp_configure() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+       $pptpcfg = $config['pptp'];
+       
+       /* generate mpd.conf */
+       $fd = fopen("{$g['varetc_path']}/mpd.conf", "w");
+       if (!$fd) {
+               printf("Error: cannot open mpd.conf in interfaces_wan_pptp_configure().\n");
+               return 1;
+       }
+               
+       $mpdconf = <<<EOD
+pptp:
+       new -i ng0 pptp pptp
+       set iface route default
+       set iface disable on-demand
+       set iface idle 0
+       set iface up-script /usr/local/sbin/ppp-linkup
+       set bundle disable multilink
+       set bundle authname "{$pptpcfg['username']}"
+       set bundle password "{$pptpcfg['password']}"
+       set link keep-alive 10 60
+       set link max-redial 0
+       set link no acfcomp protocomp
+       set link disable pap chap
+       set link accept chap
+       set ipcp no vjcomp
+       set ipcp ranges 0.0.0.0/0 0.0.0.0/0
+       open
+       
+EOD;
+
+       fwrite($fd, $mpdconf);
+       fclose($fd);
+       
+       /* generate mpd.links */
+       $fd = fopen("{$g['varetc_path']}/mpd.links", "w");
+       if (!$fd) {
+               printf("Error: cannot open mpd.links in interfaces_wan_pptp_configure().\n");
+               return 1;
+       }
+               
+       $mpdconf = <<<EOD
+pptp:
+       set link type pptp
+       set pptp mode active
+       set pptp enable originate outcall
+       set pptp self {$pptpcfg['local']}
+       set pptp peer {$pptpcfg['remote']}
+       
+EOD;
+
+       fwrite($fd, $mpdconf);
+       fclose($fd);
+       
+       /* configure interface */
+       mwexec("/sbin/ifconfig " . escapeshellarg($wancfg['if']) . " " . 
+               escapeshellarg($pptpcfg['local'] . "/" . $pptpcfg['subnet']));
+       
+       /* fire up mpd */
+       mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']} -p {$g['varrun_path']}/mpd.pid pptp");
+       
+       return 0;
+}
+
+function get_real_wan_interface() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+       
+       $wanif = $wancfg['if'];
+       if (($wancfg['ipaddr'] == "pppoe") || ($wancfg['ipaddr'] == "pptp")) {
+               $wanif = $g['pppoe_interface'];
+       }
+       
+       return $wanif;
+}
+
+function get_current_wan_address() {
+       global $config, $g;
+       
+       $wancfg = $config['interfaces']['wan'];
+       
+       if (in_array($wancfg['ipaddr'], array('pppoe','dhcp','pptp'))) {
+               /* dynamic WAN IP address, find out which one */
+               $wanif = get_real_wan_interface();
+               
+               /* get interface info with netstat */
+               exec("/usr/bin/netstat -nWI " . escapeshellarg($wanif) . " -f inet", $ifinfo);
+               
+               if (isset($ifinfo[1])) {
+                       $aif = preg_split("/\s+/", $ifinfo[1]);
+                       $curwanip = chop($aif[3]);
+                       
+                       if ($curwanip && is_ipaddr($curwanip) && ($curwanip != "0.0.0.0"))
+                               return $curwanip;
+               }
+               
+               return null;
+       } else {
+               /* static WAN IP address */
+               return $wancfg['ipaddr'];
+       }
+}
+
+?>
diff --git a/phpconf/inc/services.inc b/phpconf/inc/services.inc
new file mode 100644 (file)
index 0000000..ef79dfe
--- /dev/null
@@ -0,0 +1,345 @@
+<?php
+/*
+       services.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* include all configuration functions */
+require_once("functions.inc");
+
+function services_dhcpd_configure() {
+       global $config, $g;
+       
+       /* kill any running dhcpd */
+       killbypid("{$g['varrun_path']}/dhcpd.pid");
+       
+       $syscfg = $config['system'];
+       $dhcpdcfg = $config['dhcpd'];
+       
+       /* DHCP enabled on any interfaces? */
+       $dhcpdenable = false;
+       foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
+               if (isset($dhcpifconf['enable']) &&
+                       (($dhcpif == "lan") ||
+                       (isset($config['interfaces'][$dhcpif]['enable']) &&
+                       $config['interfaces'][$dhcpif]['if'] && (!$config['interfaces'][$dhcpif]['bridge']))))
+                       $dhcpdenable = true;
+       }
+       
+       if (!$dhcpdenable)
+               return 0;
+       
+       if ($g['booting'])
+               echo "Starting DHCP service... ";
+       else
+               sleep(1);
+       
+       /* write dhcpd.conf */
+       $fd = fopen("{$g['varetc_path']}/dhcpd.conf", "w");
+       if (!$fd) {
+               printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n");
+               return 1;
+       }
+
+       $dnscfg = "";
+       if (isset($config['dnsmasq']['enable'])) {
+               $dnscfg = "option domain-name-servers " . $config['interfaces']['lan']['ipaddr'] . ";";
+       } else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
+               $dnscfg = "option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
+       }
+       
+       $dhcpdconf = <<<EOD
+option domain-name "{$syscfg['domain']}";
+$dnscfg
+default-lease-time 7200;
+max-lease-time 86400;
+authoritative;
+log-facility local7;
+ddns-update-style none;
+
+EOD;
+       
+       $dhcpdifs = array();
+       foreach ($dhcpdcfg as $dhcpif => $dhcpifconf) {
+               
+               $ifcfg = $config['interfaces'][$dhcpif];
+               
+               if (!isset($dhcpifconf['enable']) ||
+                       (($dhcpif != "lan") &&
+                       (!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
+                       continue;
+                       
+               $subnet = gen_subnet($ifcfg['ipaddr'], $ifcfg['subnet']);
+               $subnetmask = gen_subnet_mask($ifcfg['subnet']);
+               
+               $dhcpdconf .= <<<EOD
+subnet $subnet netmask $subnetmask {
+       range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
+       option routers {$ifcfg['ipaddr']};
+
+EOD;
+
+               if ($dhcpifconf['defaultleasetime'])
+                       $dhcpdconf .= " default-lease-time {$dhcpifconf['defaultleasetime']};\n";
+               if ($dhcpifconf['maxleasetime'])
+                       $dhcpdconf .= " max-lease-time {$dhcpifconf['maxleasetime']};\n";
+                       
+               if (is_array($dhcpifconf['winsserver']) && $dhcpifconf['winsserver'][0]) {
+                       $dhcpdconf .= " option netbios-name-servers " . join(",", $dhcpifconf['winsserver']) . ";\n";
+                       $dhcpdconf .= " option netbios-node-type 8;\n";
+               }
+                       
+               $dhcpdconf .= <<<EOD
+}
+
+EOD;
+
+               /* add static mappings */
+               if (is_array($dhcpifconf['staticmap'])) {
+               
+                       $i = 0;
+                       foreach ($dhcpifconf['staticmap'] as $sm) {
+                               $dhcpdconf .= <<<EOD
+host s_{$dhcpif}_{$i} {
+       hardware ethernet {$sm['mac']};
+       fixed-address {$sm['ipaddr']};
+}
+
+EOD;
+                               $i++;
+                       }
+               }
+               
+               $dhcpdifs[] = $ifcfg['if'];
+       }
+
+       fwrite($fd, $dhcpdconf);
+       fclose($fd);
+
+       /* create an empty leases database */
+       touch("{$g['vardb_path']}/dhcpd.leases");
+       
+       /* fire up dhcpd */
+       mwexec("/usr/local/sbin/dhcpd -cf {$g['varetc_path']}/dhcpd.conf " . 
+               join(" ", $dhcpdifs));
+               
+       if (!$g['booting']) {
+               filter_configure();
+       } else
+               echo "done\n";
+       
+       return 0;
+}
+
+function services_dyndns_reset() {
+       global $config, $g;
+
+       if (file_exists("{$g['vardb_path']}/ez-ipupdate.cache")) {
+               unlink("{$g['vardb_path']}/ez-ipupdate.cache");
+       }       
+       
+       if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
+               conf_mount_rw();
+               unlink("{$g['conf_path']}/ez-ipupdate.cache");
+               conf_mount_ro();
+       }
+       
+       return 0;
+}
+
+function services_dyndns_configure() {
+       global $config, $g;
+       
+       /* kill any running ez-ipupdate */
+       /* ez-ipupdate needs SIGQUIT instead of SIGTERM */
+       sigkillbypid("{$g['varrun_path']}/ez-ipupdate.pid", "QUIT");
+       
+       $dyndnscfg = $config['dyndns'];
+       $wancfg = $config['interfaces']['wan'];
+       
+       if (isset($dyndnscfg['enable'])) {
+       
+               if ($g['booting'])
+                       echo "Starting DynDNS client... ";
+               else
+                       sleep(1);
+               
+               /* determine WAN interface name */
+               $wanif = get_real_wan_interface();
+               
+               /* write ez-ipupdate.conf */
+               $fd = fopen("{$g['varetc_path']}/ez-ipupdate.conf", "w");
+               if (!$fd) {
+                       printf("Error: cannot open ez-ipupdate.conf in services_dyndns_configure().\n");
+                       return 1;
+               }
+                       
+               $ezipupdateconf = <<<EOD
+service-type={$dyndnscfg['type']}
+user={$dyndnscfg['username']}:{$dyndnscfg['password']}
+host={$dyndnscfg['host']}
+interface=$wanif
+max-interval=2073600
+pid-file={$g['varrun_path']}/ez-ipupdate.pid
+cache-file={$g['vardb_path']}/ez-ipupdate.cache
+execute=/etc/rc.dyndns.storecache
+daemon
+
+EOD;
+
+               /* enable MX? */
+               if ($dyndnscfg['mx']) {
+                       $ezipupdateconf .= "mx={$dyndnscfg['mx']}\n";
+               }
+               
+               /* enable wildcards? */
+               if (isset($dyndnscfg['wildcard'])) {
+                       $ezipupdateconf .= "wildcard\n";
+               }
+
+               fwrite($fd, $ezipupdateconf);
+               fclose($fd);
+               
+               /* if we're booting, copy the cache file from /conf */
+               if ($g['booting']) {
+                       if (file_exists("{$g['conf_path']}/ez-ipupdate.cache")) {
+                               copy("{$g['conf_path']}/ez-ipupdate.cache", "{$g['vardb_path']}/ez-ipupdate.cache");
+                       }
+               }
+               
+               /* run ez-ipupdate */
+               mwexec("/usr/local/bin/ez-ipupdate -c {$g['varetc_path']}/ez-ipupdate.conf");
+               
+               if ($g['booting'])
+                       echo "done\n";
+       }
+       
+       return 0;
+}
+
+function services_dnsmasq_configure() {
+       global $config, $g;
+
+       /* kill any running dnsmasq */
+       sigkillbypid("{$g['varrun_path']}/dnsmasq.pid", "TERM");
+
+       if (isset($config['dnsmasq']['enable'])) {
+       
+               if ($g['booting'])
+                       echo "Starting DNS forwarder... ";
+               else
+                       sleep(1);
+
+               /* generate hosts file */
+               system_hosts_generate();
+               
+               $args = "";
+               
+               if (isset($config['dnsmasq']['regdhcp'])) {
+                       
+                       $args .= " -l {$g['vardb_path']}/dhcpd.leases" . 
+                               " -s {$config['system']['domain']}";
+               }
+
+               /* run dnsmasq */
+               mwexec("/usr/local/sbin/dnsmasq {$args}");
+
+               if ($g['booting'])
+                       echo "done\n";
+       }
+       
+       if (!$g['booting']) {
+               services_dhcpd_configure();
+       }
+
+       return 0;
+}
+
+function services_snmpd_configure() {
+       global $config, $g;
+
+       /* kill any running snmpd */
+       sigkillbypid("{$g['varrun_path']}/snmpd.pid", "TERM");
+
+       if (isset($config['snmpd']['enable'])) {
+       
+               if ($g['booting'])
+                       echo "Starting SNMP agent... ";
+
+               /* generate snmpd.conf */
+               $fd = fopen("{$g['varetc_path']}/snmpd.conf", "w");
+               if (!$fd) {
+                       printf("Error: cannot open snmpd.conf in services_snmpd_configure().\n");
+                       return 1;
+               }
+                       
+               $snmpdconf = <<<EOD
+syslocation "{$config['snmpd']['syslocation']}"
+syscontact "{$config['snmpd']['syscontact']}"
+rocommunity "{$config['snmpd']['rocommunity']}"
+
+EOD;
+
+               fwrite($fd, $snmpdconf);
+               fclose($fd);
+
+               /* run snmpd */
+               mwexec("/usr/local/sbin/snmpd -c {$g['varetc_path']}/snmpd.conf" .
+                       " -P {$g['varrun_path']}/snmpd.pid");
+
+               if ($g['booting'])
+                       echo "done\n";
+       }
+
+       return 0;
+}
+
+function services_proxyarp_configure() {
+       global $config, $g;
+
+       /* kill any running choparp */
+       killbyname("choparp");
+       
+       if (is_array($config['proxyarp']) && count($config['proxyarp']) &&
+                       (is_ipaddr($config['interfaces']['wan']['ipaddr']) ||
+                       ($config['interfaces']['wan']['ipaddr'] == "dhcp"))) {
+       
+               $args = $config['interfaces']['wan']['if'] . " auto";
+       
+               foreach ($config['proxyarp']['proxyarpnet'] as $paent) {
+                       if (isset($paent['network']))
+                               $args .= " " . escapeshellarg($paent['network']);
+                       else if (isset($paent['range']))
+                               $args .= " " . escapeshellarg($paent['range']['from'] . "-" . 
+                                       $paent['range']['to']);
+               }
+               
+               mwexec_bg("/usr/local/sbin/choparp " . $args);
+       }
+}
+
+?>
diff --git a/phpconf/inc/shaper.inc b/phpconf/inc/shaper.inc
new file mode 100644 (file)
index 0000000..aa0ad6e
--- /dev/null
@@ -0,0 +1,372 @@
+<?php
+/*
+       shaper.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+       
+/* include all configuration functions */
+require_once("functions.inc");
+       
+function shaper_configure() {
+       global $config, $g;
+       
+       if (isset($config['shaper']['enable'])) {
+       
+               if ($g['booting'])
+                       echo "Starting traffic shaper... ";
+               
+               /* generate shaper rules */
+               $shaperrules = shaper_rules_generate();
+               
+               /* make sure ipfw and dummynet are loaded */
+               mwexec("/sbin/kldload ipfw");
+               mwexec("/sbin/kldload dummynet");
+               
+               /* change one_pass to 1 so ipfw stops checking after
+                  a rule has matched */
+               mwexec("/sbin/sysctl net.inet.ip.fw.one_pass=1");
+               
+               /* load shaper rules */
+               mwexec("/sbin/ipfw -f flush");
+               mwexec("/sbin/ipfw -f pipe flush");
+               
+               /* XXX - seems like ipfw cannot accept rules directly on stdin,
+                  so we have to write them to a temporary file first */
+               $fd = fopen("{$g['tmp_path']}/ipfw.rules", "w");
+               if (!$fd) {
+                       printf("Cannot open ipfw.rules in shaper_configure()\n");
+                       return 1;
+               }
+                       
+               fwrite($fd, $shaperrules);
+               fclose($fd);
+               
+               mwexec("/sbin/ipfw {$g['tmp_path']}/ipfw.rules");
+               
+               unlink("{$g['tmp_path']}/ipfw.rules");
+               
+               /* make sure bridged packets are shaped as well */
+               mwexec("/sbin/sysctl net.link.ether.bridge_ipfw=1");
+               
+               if ($g['booting'])
+                       echo "done\n";
+               
+       } else {
+               /* unload ipfw and dummynet */
+               mwexec("/sbin/sysctl net.link.ether.bridge_ipfw=0");
+               mwexec("/sbin/kldunload dummynet");
+               mwexec("/sbin/kldunload ipfw");
+       }
+       
+       return 0;
+}
+
+function shaper_rules_generate() {
+       global $config, $g;
+
+       $wancfg = $config['interfaces']['wan'];
+       $lancfg = $config['interfaces']['lan'];
+       $pptpdcfg = $config['pptpd'];
+       
+       $lanif = $lancfg['if'];
+       $wanif = get_real_wan_interface();
+       
+       $lanip = $lancfg['ipaddr'];
+       $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
+       $lansn = $lancfg['subnet'];
+       
+       /* optional interfaces */
+       $optcfg = array();
+       
+       for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+               $oc = $config['interfaces']['opt' . $i];
+               
+               if (isset($oc['enable']) && $oc['if']) {
+                       $oic = array();
+                       $oic['ip'] = $oc['ipaddr'];
+                       $oic['if'] = $oc['if'];
+                       $oic['sa'] = gen_subnet($oc['ipaddr'], $oc['subnet']);
+                       $oic['sn'] = $oc['subnet'];
+                       
+                       $optcfg['opt' . $i] = $oic;
+               }
+       }
+       
+       if ($pptpdcfg['mode'] == "server") {
+               $pptpip = $pptpdcfg['localip'];
+               $pptpsa = $pptpdcfg['remoteip'];
+               $pptpsn = $g['pptp_subnet'];
+       }
+       
+       /* add a rule to pass all traffic from/to the firewall,
+          so the user cannot lock himself out of the webGUI */
+       $shaperrules = "add pass all from $lanip to any\n";
+       $shaperrules .= "add pass all from any to $lanip\n";
+       
+       /* generate rules */
+       if (isset($config['shaper']['rule']))   
+               foreach ($config['shaper']['rule'] as $rule) {
+               
+               /* does the rule deal with a PPTP interface? */
+               if ($rule['interface'] == "pptp") {
+               
+                       if ($pptpdcfg['mode'] != "server")
+                               continue;
+                               
+                       $nif = $g['n_pptp_units'];
+                       $ispptp = true;
+               } else {
+                       
+                       if (strstr($rule['interface'], "opt")) {
+                               if (!array_key_exists($rule['interface'], $optcfg))
+                                       continue;
+                       }
+               
+                       $nif = 1;
+                       $ispptp = false;
+               }
+               
+               if ($pptpdcfg['mode'] != "server") {
+                       if (($rule['source']['network'] == "pptp") ||
+                               ($rule['destination']['network'] == "pptp"))
+                                       continue;
+               }
+               
+               if (strstr($rule['source']['network'], "opt")) {
+                       if (!array_key_exists($rule['source']['network'], $optcfg))
+                               continue;
+               }
+               if (strstr($rule['destination']['network'], "opt")) {
+                       if (!array_key_exists($rule['destination']['network'], $optcfg))
+                               continue;
+               }
+               
+               /* check for unresolvable aliases */
+               if ($rule['source']['address'] && !alias_expand($rule['source']['address']))
+                       continue;
+               if ($rule['destination']['address'] && !alias_expand($rule['destination']['address']))
+                       continue;
+               
+               for ($iif = 0; $iif < $nif; $iif++) {
+                       
+                       /* pipe or queue? */
+                       if (isset($rule['targetpipe']) && isset($config['shaper']['pipe'][$rule['targetpipe']])) {
+                               $pipen = $rule['targetpipe'] + 1;
+                               $line = "add pipe $pipen ";
+                       } else if (isset($rule['targetqueue']) && isset($config['shaper']['queue'][$rule['targetqueue']])) {
+                               $queuen = $rule['targetqueue'] + 1;
+                               $line = "add queue $queuen ";
+                       } else {
+                               printf("Neither existing pipe nor queue found in rule $i\n");
+                               break;
+                       }
+                       
+                       if (isset($rule['protocol'])) {
+                               $line .= "{$rule['protocol']} ";
+                       } else {
+                               $line .= "all ";
+                       }
+                       
+                       /* source address */
+                       if (isset($rule['source']['any'])) {
+                               $src = "any";
+                       } else if ($rule['source']['network']) {
+                               
+                               if (strstr($rule['source']['network'], "opt")) {
+                                       $src = $optcfg[$rule['source']['network']]['sa'] . "/" .
+                                               $optcfg[$rule['source']['network']]['sn'];
+                               } else {
+                                       switch ($rule['source']['network']) {
+                                               case 'lan':
+                                                       $src = "$lansa/$lansn";
+                                                       break;
+                                               case 'pptp':
+                                                       $src = "$pptpsa/$pptpsn";
+                                                       break;
+                                       }
+                               }
+                       } else if ($rule['source']['address']) {
+                               $src = alias_expand($rule['source']['address']);
+                       }
+                       
+                       if (!$src) {
+                               printf("No source address found in rule $i\n");
+                               break;
+                       }
+                       
+                       if (isset($rule['source']['not'])) {
+                               $line .= "from not $src ";
+                       } else {
+                               $line .= "from $src ";
+                       }
+                       
+                       if (in_array($rule['protocol'], array("tcp","udp"))) {
+                               
+                               if ($rule['source']['port']) {
+                                       $srcport = explode("-", $rule['source']['port']);
+                                       
+                                       if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
+                                               $line .= "{$srcport[0]} ";
+                                       } else {
+                                               $line .= "{$srcport[0]}-{$srcport[1]} ";
+                                       }
+                               }
+                       }
+                       
+                       /* destination address */
+                       if (isset($rule['destination']['any'])) {
+                               $dst = "any";
+                       } else if ($rule['destination']['network']) {
+                               
+                               if (strstr($rule['destination']['network'], "opt")) {
+                                       $dst = $optcfg[$rule['destination']['network']]['sa'] . "/" .
+                                               $optcfg[$rule['destination']['network']]['sn'];
+                               } else {
+                                       switch ($rule['destination']['network']) {
+                                               case 'lan':
+                                                       $dst = "$lansa/$lansn";
+                                                       break;
+                                               case 'pptp':
+                                                       $dst = "$pptpsa/$pptpsn";
+                                                       break;
+                                       }
+                               }
+                       } else if ($rule['destination']['address']) {
+                               $dst = alias_expand($rule['destination']['address']);
+                       }
+                       
+                       if (!$dst) {
+                               printf("No destination address found in rule $i\n");
+                               break;
+                       }
+                       
+                       if (isset($rule['destination']['not'])) {
+                               $line .= "to not $dst ";
+                       } else {
+                               $line .= "to $dst ";
+                       }
+                       
+                       if (in_array($rule['protocol'], array("tcp","udp"))) {
+                               
+                               if ($rule['destination']['port']) {
+                                       $dstport = explode("-", $rule['destination']['port']);
+                                       
+                                       if ((!$dstport[1]) || ($dstport[0] == $dstport[1])) {
+                                               $line .= "{$dstport[0]} ";
+                                       } else {
+                                               $line .= "{$dstport[0]}-{$dstport[1]} ";
+                                       }
+                               }
+                       }
+                       
+                       if ($rule['iplen'])
+                               $line .= "iplen {$rule['iplen']} ";
+                       
+                       if ($rule['tcpflags'])
+                               $line .= "tcpflags {$rule['tcpflags']} ";
+                               
+                       if ($rule['direction'] == "in")
+                               $line .= "in ";
+                       else if ($rule['direction'] == "out")
+                               $line .= "out ";
+                       
+                       if ($ispptp) {
+                               $line .= "via ng" . ($iif+1);
+                       } else {
+                               if ($rule['interface'] == "wan")
+                                       $if = $wanif;
+                               else
+                                       $if = $config['interfaces'][$rule['interface']]['if'];
+                                       
+                               $line .= "via {$if}";
+                       }
+                       
+                       $line .= "\n";
+                       $shaperrules .= $line;
+               }
+               
+               $i++;
+       }
+       
+       /* generate pipes */
+       if (isset($config['shaper']['pipe'])) {
+               $pipei = 1;
+               foreach ($config['shaper']['pipe'] as $pipe) {
+                       $line = "pipe $pipei config bw {$pipe['bandwidth']}Kbit/s ";
+                       
+                       if ($pipe['delay']) {
+                               $line .= "delay {$pipe['delay']} ";
+                       }
+                       
+                       switch ($pipe['mask']) {
+                               case 'source':
+                                       $line .= "mask src-ip 0xffffffff ";
+                                       break;
+                               case 'destination':
+                                       $line .= "mask dst-ip 0xffffffff ";
+                                       break;
+                       }
+                       
+                       $line .= "\n";
+                       $shaperrules .= $line;
+                       $pipei++;
+               }
+       }
+       
+       /* generate queues */
+       if (isset($config['shaper']['queue'])) {
+               $queuei = 1;
+               foreach ($config['shaper']['queue'] as $queue) {
+                       
+                       $pipen = $queue['targetpipe'] + 1;
+                       if (!isset($queue['targetpipe']) || !isset($config['shaper']['pipe'][$queue['targetpipe']])) {
+                               printf("Pipe $pipen for queue $queuei not found!\n");
+                               continue;
+                       }
+                       
+                       $line = "queue $queuei config pipe {$pipen}";
+                       $line .= " weight {$queue['weight']}";
+                       
+                       switch ($queue['mask']) {
+                               case 'source':
+                                       $line .= " mask src-ip 0xffffffff ";
+                                       break;
+                               case 'destination':
+                                       $line .= " mask dst-ip 0xffffffff ";
+                                       break;
+                       }
+                       
+                       $line .= "\n";
+                       $shaperrules .= $line;
+                       $queuei++;
+               }
+       }
+
+       return $shaperrules;
+}
+
+?>
diff --git a/phpconf/inc/system.inc b/phpconf/inc/system.inc
new file mode 100644 (file)
index 0000000..60b4bbd
--- /dev/null
@@ -0,0 +1,466 @@
+<?php
+/*
+       system.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* include all configuration functions */
+require_once("functions.inc");
+       
+function system_resolvconf_generate($dynupdate = false) {
+       global $config, $g;
+       
+       $syscfg = $config['system'];
+       
+       $fd = fopen("{$g['varetc_path']}/resolv.conf", "w");
+       if (!$fd) {
+               printf("Error: cannot open resolv.conf in system_resolvconf_generate().\n");
+               return 1;
+       }
+               
+       $resolvconf = "domain {$syscfg['domain']}\n";
+       
+       $havedns = false;
+       
+       if (isset($syscfg['dnsallowoverride'])) {
+               /* get dynamically assigned DNS servers (if any) */
+               $nfd = @fopen("{$g['varetc_path']}/nameservers.conf", "r");
+               if ($nfd) {
+                       while (!feof($nfd)) {
+                               $dnss = trim(fgets($nfd));
+                               if ($dnss) {
+                                       $resolvconf .= "nameserver $dnss\n";
+                                       $havedns = true;
+                               }
+                       }
+                       fclose($nfd);
+               }
+       }
+       if (!$havedns && is_array($syscfg['dnsserver'])) {
+               foreach ($syscfg['dnsserver'] as $ns) {
+                       if ($ns)
+                               $resolvconf .= "nameserver $ns\n";
+                       $havedns = true;
+               }
+       }
+               
+       fwrite($fd, $resolvconf);
+       fclose($fd);
+       
+       if (!$g['booting']) {
+               /* restart dhcpd (nameservers may have changed) */
+               if (!$dynupdate)
+                       services_dhcpd_configure();
+       }
+       
+       return 0;
+}
+
+function system_hosts_generate() {
+       global $config, $g;
+       
+       $syscfg = $config['system'];
+       $lancfg = $config['interfaces']['lan'];
+       $dnsmasqcfg = $config['dnsmasq'];
+
+       if (!is_array($dnsmasqcfg['hosts'])) {
+               $dnsmasqcfg['hosts'] = array();
+       }
+       $hostscfg = $dnsmasqcfg['hosts'];
+       
+       $fd = fopen("{$g['varetc_path']}/hosts", "w");
+       if (!$fd) {
+               printf("Error: cannot open hosts file in system_hosts_generate().\n");
+               return 1;
+       }
+               
+       $hosts = <<<EOD
+127.0.0.1      localhost localhost.{$syscfg['domain']}
+{$lancfg['ipaddr']}    {$syscfg['hostname']}.{$syscfg['domain']} {$syscfg['hostname']}
+
+EOD;
+       
+       foreach ($hostscfg as $host) {
+               if ($host['host'])
+                       $hosts .= "{$host['ip']}        {$host['host']}.{$host['domain']} {$host['host']}\n";
+               else
+                       $hosts .= "{$host['ip']}        {$host['domain']}\n";
+       }
+       fwrite($fd, $hosts);
+       fclose($fd);
+       
+       return 0;
+}
+
+function system_hostname_configure() {
+       global $config, $g;
+       
+       $syscfg = $config['system'];
+       
+       /* set hostname */
+       return mwexec("/bin/hostname " .
+               escapeshellarg("{$syscfg['hostname']}.{$syscfg['domain']}"));
+}
+
+function system_routing_configure() {
+       global $config, $g;
+       
+       /* clear out old routes, if necessary */
+       if (file_exists("{$g['vardb_path']}/routes.db")) {
+               $fd = fopen("{$g['vardb_path']}/routes.db", "r");
+               if (!$fd) {
+                       printf("Error: cannot open routes DB file in system_routing_configure().\n");
+                       return 1;               
+               }
+               while (!feof($fd)) {
+                       $oldrt = fgets($fd);
+                       if ($oldrt)
+                               mwexec("/sbin/route delete " . escapeshellarg($oldrt));
+               }
+               fclose($fd);
+               unlink("{$g['vardb_path']}/routes.db");
+       }
+       
+       if (is_array($config['staticroutes']['route'])) {
+               
+               $fd = fopen("{$g['vardb_path']}/routes.db", "w");
+               if (!$fd) {
+                       printf("Error: cannot open routes DB file in system_routing_configure().\n");
+                       return 1;               
+               }
+               
+               foreach ($config['staticroutes']['route'] as $rtent) {
+                       mwexec("/sbin/route add " . escapeshellarg($rtent['network']) . 
+                               " " . escapeshellarg($rtent['gateway']));
+                       
+                       /* record route so it can be easily removed later (if necessary) */
+                       fwrite($fd, $rtent['network'] . "\n");
+               }
+               
+               fclose($fd); 
+       }
+       
+       return 0;
+}
+
+function system_routing_enable() {
+       global $config, $g;
+       
+       return mwexec("/sbin/sysctl net.inet.ip.forwarding=1");
+}
+
+function system_syslogd_start() {
+       global $config, $g;
+       
+       $syslogcfg = $config['syslog'];
+
+       if ($g['booting']) 
+               echo "Starting syslog service... ";
+       else
+               killbypid("{$g['varrun_path']}/syslog.pid");
+                       
+       if (isset($syslogcfg['enable'])) {
+
+               /* write syslog.conf */
+               $fd = fopen("{$g['varetc_path']}/syslog.conf", "w");
+               if (!$fd) {
+                       printf("Error: cannot open syslog.conf in system_syslogd_start().\n");
+                       return 1;
+               }
+               
+               $syslogconf = <<<EOD
+local0.*                                       %/var/log/filter.log
+local7.*                                       %/var/log/dhcpd.log
+*.notice;kern.debug;lpr.info;mail.crit;news.err;local0.none;local7.none %/var/log/system.log
+security.*                                     %/var/log/system.log
+auth.info;authpriv.info;daemon.info            %/var/log/system.log
+*.emerg                                                *
+
+EOD;
+
+
+               if (isset($syslogcfg['filter'])) {
+                       $syslogconf .= <<<EOD
+local0.*                                       @{$syslogcfg['remoteserver']}
+
+EOD;
+               }
+
+               if (isset($syslogcfg['dhcp'])) {
+                       $syslogconf .= <<<EOD
+local7.*                                       @{$syslogcfg['remoteserver']}
+
+EOD;
+               }
+
+               if (isset($syslogcfg['system'])) {
+                       $syslogconf .= <<<EOD
+*.notice;kern.debug;lpr.info;mail.crit;news.err;local0.none;local7.none @{$syslogcfg['remoteserver']}
+security.*                                     @{$syslogcfg['remoteserver']}
+auth.info;authpriv.info;daemon.info            @{$syslogcfg['remoteserver']}
+*.emerg                                                @{$syslogcfg['remoteserver']}
+
+EOD;
+               }
+
+               fwrite($fd, $syslogconf);
+               fclose($fd);
+               
+               $retval = mwexec("/usr/sbin/syslogd -s -f {$g['varetc_path']}/syslog.conf");
+
+       } else {
+               $retval = mwexec("/usr/sbin/syslogd -ss");
+       }
+       
+       if ($g['booting'])
+               echo "done\n";
+               
+       return $retval;
+}
+
+function system_pccard_start() {
+       global $config, $g;
+       
+       if ($g['booting'])
+               echo "Initializing PC cards... ";
+       
+       /* kill any running pccardd */
+       killbypid("{$g['varrun_path']}/pccardd.pid");
+       
+       /* fire up pccardd */
+       $res = mwexec("/usr/sbin/pccardd -z -f {$g['etc_path']}/pccard.conf");
+       
+       if ($g['booting']) {
+               if ($res == 0)
+                       echo "done\n";
+               else
+                       echo "failed (probably no PC card controller present)\n";
+       }
+               
+       return $res;
+}
+
+function system_webgui_start() {
+       global $config, $g;
+       
+       if ($g['booting'])
+               echo "Starting webGUI... ";
+       
+       /* kill any running mini_httpd */
+       killbypid("{$g['varrun_path']}/mini_httpd.pid");
+       
+       /* generate password file */
+       system_password_configure();
+       
+       chdir($g['www_path']);
+       
+       /* non-standard port? */
+       if ($config['system']['webgui']['port'])
+               $portarg = "-p {$config['system']['webgui']['port']}";
+       else
+               $portarg = "";
+       
+       if ($config['system']['webgui']['protocol'] == "https") {
+       
+               if ($config['system']['webgui']['certificate'] && $config['system']['webgui']['private-key']) {
+                       $cert = base64_decode($config['system']['webgui']['certificate']);
+                       $key = base64_decode($config['system']['webgui']['private-key']);
+               } else {
+                       /* default certificate/key */
+                       $cert = <<<EOD
+-----BEGIN CERTIFICATE-----
+MIIBlDCB/gIBADANBgkqhkiG9w0BAQQFADATMREwDwYDVQQKEwhtMG4wd2FsbDAe
+Fw0wMzA5MDgxNzAzNDZaFw0wNDA5MDcxNzAzNDZaMBMxETAPBgNVBAoTCG0wbjB3
+YWxsMIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDAShszhFz+o8lsMWTGgTxs
+TMPR+v4+qL5jXDyY97MLTGFK7aqQOtpIQc+TcTc4jklgOVlHoR7oBXrsi8YrbCd+
+83LPQmQoSPC0VqhfU3uYf3NzxiK8r97aPCsmWgwT2pQ6TcESTm6sF7nLprOf/zFP
+C4jE2fvjkbzyVolPywBuewIDAQABMA0GCSqGSIb3DQEBBAUAA4GBAK2D8NqQSlUs
+pFCe5J9ue1LrjfGHHy4HE9zA9avgrz3Qju+1JOshEwy/1BJjZ93tQUbiRS7RwvDO
+4crGG4IejjhFczzA2CIX3rd2rYM2oGpojKgm5YuuhV5lYPwAHUOLbBaLOVqlLhzw
+VqjD7R2DkXUIfhJ5ZekqK5ZwzqJXta8U
+-----END CERTIFICATE-----
+
+EOD;
+
+                       $key = <<<EOD
+-----BEGIN RSA PRIVATE KEY-----
+MIICXQIBAAKBgQDAShszhFz+o8lsMWTGgTxsTMPR+v4+qL5jXDyY97MLTGFK7aqQ
+OtpIQc+TcTc4jklgOVlHoR7oBXrsi8YrbCd+83LPQmQoSPC0VqhfU3uYf3NzxiK8
+r97aPCsmWgwT2pQ6TcESTm6sF7nLprOf/zFPC4jE2fvjkbzyVolPywBuewIDAQAB
+AoGAbJJrQW9fQrggJuLMz/hwsYW2m31oyOBmf5u463YQtjRuSuxe/gj87weZuNqY
+H2rXq2k2K+ehl8hgW+egASyUL3L7kCkEAsVREujKTEyhSqqIRDPWTxo9S/YA9Gvn
+2ZnJvkrcKjqCO9aHX3rvJOK/ErYI6akctgI3KmgkYw5XNmECQQDuZU97RTWH9rmP
+aQr57ysNXxgFsyhetOOqeYkPtIVwpOiNbfwE1zi5RGdtO4Ku3fG1lV4J2UoWJ9yD
+awdoyYIHAkEAzn0xJ90IjPsHk+8SODEj5JGdHSZPNu1tgtrbjEi9sfGWg4K7XTxr
+QW90pWb1bKKU1uh5FzW6OhnFfuQXt1kC7QJAPSthqY+onKqCEnoxhtAHi/bKgyvl
+P+fKQwPMV2tKkgy+XwvJjrRqqZ8TqsOKVLQ+QQmCh6RpjiXMPyxHSmvqIQJBAKLR
+HF1ucDuaBROkwx0DwmWMW/KMLpIFDQDNSaiIAuu4rxHrl4mhBoGGPNffI04RtILw
+s+qVNs5xW8T+XaT4ztECQQDFHPnZeoPWE5z+AX/UUQIUWaDExz3XRzmIxRbOrlFi
+CsF1s0TdJLi/wzNQRAL37A8vqCeVFR/ng3Xpg96Yg+8Z
+-----END RSA PRIVATE KEY-----
+
+EOD;
+               }
+               
+               $fd = fopen("{$g['varetc_path']}/cert.pem", "w");
+               if (!$fd) {
+                       printf("Error: cannot open cert.pem in system_webgui_start().\n");
+                       return 1;
+               }
+               chmod("{$g['varetc_path']}/cert.pem", 0600);
+               fwrite($fd, $cert);
+               fwrite($fd, "\n");
+               fwrite($fd, $key);
+               fclose($fd);
+       
+               $res = mwexec("/usr/local/sbin/mini_httpd -S -E {$g['varetc_path']}/cert.pem" .
+                       " -c \"**.php\" -u root $portarg" .
+                       " -i {$g['varrun_path']}/mini_httpd.pid");
+       } else {
+               $res = mwexec("/usr/local/sbin/mini_httpd -c \"**.php\" -u root" .
+                       " $portarg -i {$g['varrun_path']}/mini_httpd.pid");
+       }
+       
+       if ($g['booting']) {
+               if ($res == 0)
+                       echo "done\n";
+               else
+                       echo "failed\n";
+       }
+       
+       return $res;
+}
+
+function system_password_configure() {
+       global $config, $g;
+       
+       $fd = fopen("{$g['varrun_path']}/htpasswd", "w");
+       if (!$fd) {
+               printf("Error: cannot open htpasswd in system_password_configure().\n");
+               return 1;
+       }
+       
+       if ($config['system']['username'])
+               $username = $config['system']['username'];
+       else
+               $username = "admin";
+       
+       fwrite($fd, $username . ":" . $config['system']['password'] . "\n");
+       fclose($fd);
+       chmod("{$g['varrun_path']}/htpasswd", 0600);
+       
+       return 0;
+}
+
+function system_timezone_configure() {
+       global $config, $g;
+
+       $syscfg = $config['system'];
+
+       if ($g['booting'])
+               echo "Initializing timezone... ";
+
+       /* extract appropriate timezone file */
+       $timezone = $syscfg['timezone'];
+       if (!$timezone)
+               $timezone = "Etc/UTC";
+               
+       exec("/usr/bin/tar xzfO /usr/share/zoneinfo.tgz " . 
+               escapeshellarg($timezone) . " > /etc/localtime");
+
+       if ($g['booting'])
+               echo "done\n";
+}
+
+function system_ntp_configure() {
+       global $config, $g;
+
+       $syscfg = $config['system'];
+
+       if ($g['booting'])
+               echo "Starting NTP client... ";
+       else {
+               killbypid("{$g['varrun_path']}/runmsntp.pid");
+               killbypid("{$g['varrun_path']}/msntp.pid");
+       }
+
+       /* start ntp client if needed - needs to be forced into background */
+       $updateinterval = $syscfg['time-update-interval'];
+       
+       if ($updateinterval > 0) {
+               if ($updateinterval < 6)
+                       $updateinterval = 6;
+               
+               $timeservers = "";
+               foreach (explode(' ', $syscfg['timeservers']) as $ts)
+                       $timeservers .= " " . $ts;
+               
+               mwexec_bg("/usr/local/bin/runmsntp.sh " .
+                       escapeshellarg("{$g['varrun_path']}/runmsntp.pid") . " " .
+                       escapeshellarg("{$g['varrun_path']}/msntp.pid") . " " .
+                       escapeshellarg($updateinterval) . " " .
+                       escapeshellarg($timeservers));
+       }
+               
+       if ($g['booting'])
+               echo "done\n";
+}
+
+function system_reboot() {
+       global $g;
+       
+       mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
+}
+
+function system_reboot_sync() {
+       global $g;
+       
+       mwexec("/etc/rc.reboot > /dev/null 2>&1");
+}
+
+function system_do_shell_commands() {
+       global $config, $g;
+       
+       if (is_array($config['system']['shellcmd'])) {
+               
+               foreach ($config['system']['shellcmd'] as $cmd) {
+                       exec($cmd);
+               }
+       }
+}
+
+function system_console_configure() {
+       global $config, $g;
+       
+       if (isset($config['system']['disableconsolemenu'])) {
+               touch("{$g['varetc_path']}/disableconsole");
+       } else {
+               unlink_if_exists("{$g['varetc_path']}/disableconsole");
+       }
+}
+
+?>
diff --git a/phpconf/inc/util.inc b/phpconf/inc/util.inc
new file mode 100644 (file)
index 0000000..cf5fecb
--- /dev/null
@@ -0,0 +1,392 @@
+<?php
+/*
+       util.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* kill a process by pid file */
+function killbypid($pidfile) {
+       sigkillbypid($pidfile, "TERM");
+}
+
+/* sigkill a process by pid file */
+function sigkillbypid($pidfile, $sig) {
+       if (file_exists($pidfile)) {
+               mwexec("/bin/kill -s $sig `/bin/cat " . $pidfile . "`");
+       }
+}
+
+/* kill a process by name */
+function killbyname($procname) {
+       mwexec("/usr/bin/killall " . escapeshellarg($procname));
+}
+
+/* return the subnet address given a host address and a subnet bit count */
+function gen_subnet($ipaddr, $bits) {
+       if (!is_ipaddr($ipaddr) || !is_numeric($bits))
+               return "";
+       
+       return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits));
+}
+
+/* return the highest address in the subnet given a host address and a subnet bit count */
+function gen_subnet_max($ipaddr, $bits) {
+       if (!is_ipaddr($ipaddr) || !is_numeric($bits))
+               return "";
+       
+       return long2ip(ip2long($ipaddr) | gen_subnet_mask_long($bits));
+}
+
+/* returns a subnet mask (long given a bit count) */
+function gen_subnet_mask_long($bits) {
+       $sm = 0;
+       for ($i = 0; $i < $bits; $i++) {
+               $sm >>= 1;
+               $sm |= 0x80000000;
+       }
+       return $sm;
+}
+
+/* same as above but returns a string */
+function gen_subnet_mask($bits) {
+       return long2ip(gen_subnet_mask_long($bits));
+}
+
+/* returns true if $ipaddr is a valid dotted IPv4 address */
+function is_ipaddr($ipaddr) {
+       if (!is_string($ipaddr))
+               return false;
+               
+       $ip_long = ip2long($ipaddr);
+       $ip_reverse = long2ip($ip_long);
+       if ($ipaddr == $ip_reverse)
+               return true;
+       else
+               return false;
+}
+
+/* returns true if $ipaddr is a valid dotted IPv4 address or an alias thereof */
+function is_ipaddroralias($ipaddr) {
+       
+       global $aliastable;
+       
+       if (isset($aliastable[$ipaddr]) && is_ipaddr($aliastable[$ipaddr]))
+               return true;
+       else
+               return is_ipaddr($ipaddr);
+}
+
+/* returns true if $ipaddr is a valid dotted IPv4 address or any alias */
+function is_ipaddroranyalias($ipaddr) {
+       
+       global $aliastable;
+       
+       if (isset($aliastable[$ipaddr]))
+               return true;
+       else
+               return is_ipaddr($ipaddr);
+}
+
+/* returns true if $subnet is a valid subnet in CIDR format */
+function is_subnet($subnet) {
+       if (!is_string($subnet))
+               return false;
+               
+       list($hp,$np) = explode('/', $subnet);
+       
+       if (!is_ipaddr($hp))
+               return false;
+       
+       if (!is_numeric($np) || ($np < 1) || ($np > 32))
+               return false;
+               
+       return true;
+}
+
+/* returns true if $subnet is a valid subnet in CIDR format or an alias thereof */
+function is_subnetoralias($subnet) {
+       
+       global $aliastable;
+       
+       if (isset($aliastable[$subnet]) && is_subnet($aliastable[$subnet]))
+               return true;
+       else
+               return is_subnet($subnet);
+}
+
+/* returns true if $hostname is a valid hostname */
+function is_hostname($hostname) {
+       if (!is_string($hostname))
+               return false;
+               
+       if (preg_match("/^[a-z0-9\-]+$/i", $hostname))
+               return true;
+       else
+               return false;
+}
+
+/* returns true if $domain is a valid domain name */
+function is_domain($domain) {
+       if (!is_string($domain))
+               return false;
+               
+       if (preg_match("/^([a-z0-9\-]+\.?)*$/i", $domain))
+               return true;
+       else
+               return false;
+}
+
+/* returns true if $uname is a valid DynDNS username */
+function is_dyndns_username($uname) {
+       if (!is_string($uname))
+               return false;
+               
+       if (preg_match("/[^a-z0-9\-.@_]/i", $uname))
+               return false;
+       else
+               return true;
+}
+
+/* returns true if $macaddr is a valid MAC address */
+function is_macaddr($macaddr) {
+       if (!is_string($macaddr))
+               return false;
+               
+       $maca = explode(":", $macaddr);
+       if (count($maca) != 6)
+               return false;
+       
+       foreach ($maca as $macel) {
+               if (($macel === "") || (strlen($macel) > 2))
+                       return false;
+               if (preg_match("/[^0-9a-f]/i", $macel))
+                       return false;
+       }
+       
+       return true;
+}
+
+/* returns true if $name is a valid name for an alias */
+function is_validaliasname($name) {
+       if (!preg_match("/[^a-zA-Z0-9]/", $name))
+               return true;
+       else
+               return false;
+}
+
+/* returns true if $port is a valid TCP/UDP port */
+function is_port($port) {
+       if (!is_numericint($port))
+               return false;
+               
+       if (($port < 1) || ($port > 65535))
+               return false;
+       else
+               return true;
+}
+
+/* returns a list of interfaces with MAC addresses */
+function get_interface_list() {
+       
+       global $g;
+       
+       /* build interface list with netstat */
+       exec("/usr/bin/netstat -inW -f link", $linkinfo);
+       array_shift($linkinfo);
+       
+       $iflist = array();
+       
+       foreach ($linkinfo as $link) {
+               $alink = preg_split("/\s+/", $link);
+               $ifname = chop($alink[0]);
+               
+               if (substr($ifname, -1) == "*")
+                       $ifname = substr($ifname, 0, strlen($ifname) - 1);
+               
+               if (!preg_match("/^(ppp|sl|gif|faith|lo|ng|tun)/", $ifname)) {
+                       $iflist[$ifname] = array();
+                       $iflist[$ifname]['mac'] = chop($alink[3]);
+                       $iflist[$ifname]['up'] = false;
+                       
+                       /* find out if the link on this interface is up */
+                       unset($ifinfo);
+                       exec("/sbin/ifconfig {$ifname}", $ifinfo);
+                       
+                       foreach ($ifinfo as $ifil) {
+                               if (preg_match("/status: (.*)$/", $ifil, $matches)) {
+                                       if ($matches[1] == "active")
+                                               $iflist[$ifname]['up'] = true;
+                                       break;
+                               }
+                       }
+               }
+       }
+       
+       return $iflist;
+}
+
+/* wrapper for exec() */
+function mwexec($command) {
+
+       global $g;
+       
+       if ($g['debug']) {
+               if (!$_SERVER['REMOTE_ADDR'])
+                       echo "mwexec(): $command\n";
+               passthru($command, $retval);
+       } else {
+               exec("$command > /dev/null 2>&1", $oarr, $retval);
+       }
+       
+       return $retval; 
+}
+
+/* wrapper for exec() in background */
+function mwexec_bg($command) {
+
+       global $g;
+       
+       if ($g['debug']) {
+               if (!$_SERVER['REMOTE_ADDR'])
+                       echo "mwexec(): $command\n";
+       }
+       
+       exec("nohup $command > /dev/null 2>&1 &");
+}
+
+/* unlink a file, if it exists */
+function unlink_if_exists($fn) {
+       if (file_exists($fn))
+               unlink($fn);
+}
+
+/* make a global alias table (for faster lookups) */
+function alias_make_table() {
+       
+       global $config, $g, $aliastable;
+       
+       $aliastable = array();
+       
+       if (is_array($config['aliases']['alias'])) {
+               foreach ($config['aliases']['alias'] as $alias) {
+                       if ($alias['name'])
+                               $aliastable[$alias['name']] = $alias['address'];
+               }
+       }
+}
+
+/* check if an alias exists */
+function is_alias($name) {
+       
+       global $aliastable;
+       
+       return isset($aliastable[$name]);
+}
+
+/* expand a host or network alias, if necessary */
+function alias_expand($name) {
+       
+       global $aliastable;
+       
+       if (isset($aliastable[$name]))
+               return $aliastable[$name];
+       else if (is_ipaddr($name) || is_subnet($name))
+               return $name;
+       else
+               return null;
+}
+
+/* expand a host alias, if necessary */
+function alias_expand_host($name) {
+       
+       global $aliastable;
+       
+       if (isset($aliastable[$name]) && is_ipaddr($aliastable[$name]))
+               return $aliastable[$name];
+       else if (is_ipaddr($name))
+               return $name;
+       else
+               return null;
+}
+
+/* expand a network alias, if necessary */
+function alias_expand_net($name) {
+       
+       global $aliastable;
+       
+       if (isset($aliastable[$name]) && is_subnet($aliastable[$name]))
+               return $aliastable[$name];
+       else if (is_subnet($name))
+               return $name;
+       else
+               return null;
+}
+
+/* find out whether two subnets overlap */
+function check_subnets_overlap($subnet1, $bits1, $subnet2, $bits2) {
+
+       if (!is_numeric($bits1))
+               $bits1 = 32;
+       if (!is_numeric($bits2))
+               $bits2 = 32;
+
+       if ($bits1 < $bits2)
+               $relbits = $bits1;
+       else
+               $relbits = $bits2;
+       
+       $sn1 = gen_subnet_mask_long($relbits) & ip2long($subnet1);
+       $sn2 = gen_subnet_mask_long($relbits) & ip2long($subnet2);
+       
+       if ($sn1 == $sn2)
+               return true;
+       else
+               return false;
+}
+
+/* compare two IP addresses */
+function ipcmp($a, $b) {
+       if (ip2long($a) < ip2long($b))
+               return -1;
+       else if (ip2long($a) > ip2long($b))
+               return 1;
+       else
+               return 0;
+}
+
+/* verify (and remove) the digital signature on a file - returns 0 if OK */
+function verify_digital_signature($fname) {
+
+       global $g;
+
+       return mwexec("/usr/local/bin/verifysig " .
+               escapeshellarg("{$g['etc_path']}/pubkey.pem") . " " .
+               escapeshellarg($fname));
+}
+
+?>
diff --git a/phpconf/inc/vpn.inc b/phpconf/inc/vpn.inc
new file mode 100644 (file)
index 0000000..df33dc5
--- /dev/null
@@ -0,0 +1,545 @@
+<?php
+/*
+       vpn.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+       
+/* include all configuration functions */
+require_once("functions.inc");
+       
+function vpn_ipsec_configure($ipchg = false) {
+       global $config, $g;
+       
+       $curwanip = get_current_wan_address();
+       
+       if ($ipchg) {
+               /*      dhclient or MPD told us that the IP address has changed;
+                       let's see if that's really true to avoid reloading the whole
+                       IPsec stuff when it's not really necessary (dhclient likes to
+                       execute its dhclient-exit-hooks also on renewals)
+               */              
+               if (file_exists("{$g['vardb_path']}/ipsec.wanip")) {
+                       $oldwanip = chop(file_get_contents("{$g['vardb_path']}/ipsec.wanip"));
+                       
+                       if ($curwanip == $oldwanip)
+                               return 0;       /* nothing to do */
+               }
+       }
+       
+       $syscfg = $config['system'];
+       $ipseccfg = $config['ipsec'];
+       $lancfg = $config['interfaces']['lan'];
+       $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
+       
+       if ($g['booting']) {
+               if (!isset($ipseccfg['enable']))
+                       return 0;
+               
+               echo "Configuring IPsec VPN... ";
+       } else {
+               /* kill racoon */
+               killbypid("{$g['varrun_path']}/racoon.pid");
+               
+               /* wait for process to die */
+               sleep(2);
+               
+               /* send a SIGKILL to be sure */
+               sigkillbypid("{$g['varrun_path']}/racoon.pid", "KILL");
+       }
+       
+       /* flush SPD and SAD */
+       mwexec("/usr/sbin/setkey -FP");
+       mwexec("/usr/sbin/setkey -F");
+       
+       if (isset($ipseccfg['enable'])) {
+               
+               if (!$curwanip) {
+                       /* IP address not configured yet, exit */
+                       if ($g['booting'])
+                               echo "done\n";
+                       return 0;
+               }
+               
+               if ((is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) ||
+                               isset($ipseccfg['mobileclients']['enable'])) {
+               
+                       if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel'])) {
+                       
+                               /* generate spd.conf */
+                               $fd = fopen("{$g['varetc_path']}/spd.conf", "w");
+                               if (!$fd) {
+                                       printf("Error: cannot open spd.conf in vpn_ipsec_configure().\n");
+                                       return 1;
+                               }
+                                       
+                               $spdconf = "";
+                               foreach ($ipseccfg['tunnel'] as $tunnel) {
+                               
+                                       if (isset($tunnel['disabled']))
+                                               continue;
+                               
+                                       $ep = vpn_endpoint_determine($tunnel, $curwanip);
+                                       if (!$ep)
+                                               continue;
+                                       
+                                       vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
+                                       
+                                       $spdconf .= "spdadd {$sa}/{$sn} " . 
+                                               "{$tunnel['remote-subnet']} any -P out ipsec " . 
+                                               "{$tunnel['p2']['protocol']}/tunnel/{$ep}-" .
+                                               "{$tunnel['remote-gateway']}/unique;\n";
+                                               
+                                       $spdconf .= "spdadd {$tunnel['remote-subnet']} " . 
+                                               "{$sa}/{$sn} any -P in ipsec " . 
+                                               "{$tunnel['p2']['protocol']}/tunnel/{$tunnel['remote-gateway']}-" .
+                                               "{$ep}/unique;\n";
+                               }
+                               
+                               fwrite($fd, $spdconf);
+                               fclose($fd);
+                       
+                               /* load SPD */
+                               mwexec("/usr/sbin/setkey -c < {$g['varetc_path']}/spd.conf");
+                       }
+                       
+                       /* generate racoon.conf */
+                       $fd = fopen("{$g['varetc_path']}/racoon.conf", "w");
+                       if (!$fd) {
+                               printf("Error: cannot open racoon.conf in vpn_ipsec_configure().\n");
+                               return 1;
+                       }
+                               
+                       $racoonconf = "path pre_shared_key \"{$g['varetc_path']}/psk.txt\";\n\n";
+                       
+                       if (is_array($ipseccfg['tunnel']) && count($ipseccfg['tunnel']))
+                               foreach ($ipseccfg['tunnel'] as $tunnel) {
+                       
+                               if (isset($tunnel['disabled']))
+                                       continue;
+                               
+                               $ep = vpn_endpoint_determine($tunnel, $curwanip);
+                               if (!$ep)
+                                       continue;
+                       
+                               vpn_localnet_determine($tunnel['local-subnet'], $sa, $sn);
+                       
+                               if (isset($tunnel['p1']['myident']['myaddress'])) {
+                                       $myidentt = "address";
+                                       $myident = $ep;
+                               } else if (isset($tunnel['p1']['myident']['address'])) {
+                                       $myidentt = "address";
+                                       $myident = $tunnel['p1']['myident']['address'];
+                               } else if (isset($tunnel['p1']['myident']['fqdn'])) {
+                                       $myidentt = "fqdn";
+                                       $myident = $tunnel['p1']['myident']['fqdn'];
+                               }
+                       
+                               $racoonconf .= <<<EOD
+remote {$tunnel['remote-gateway']} \{
+       exchange_mode {$tunnel['p1']['mode']};
+       my_identifier {$myidentt} "{$myident}";
+       peers_identifier address {$tunnel['remote-gateway']};
+       initial_contact on;
+       support_proxy on;
+       proposal_check obey;
+       proposal \{
+               encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
+               hash_algorithm {$tunnel['p1']['hash-algorithm']};
+               authentication_method pre_shared_key;
+               dh_group {$tunnel['p1']['dhgroup']};
+
+EOD;
+                               if ($tunnel['p1']['lifetime'])
+                                       $racoonconf .= "                lifetime time {$tunnel['p1']['lifetime']} secs;\n";
+                               
+                               $racoonconf .= "        }\n";
+                               
+                               if ($tunnel['p1']['lifetime'])
+                                       $racoonconf .= "        lifetime time {$tunnel['p1']['lifetime']} secs;\n";
+                                       
+                               $racoonconf .= "}\n\n";
+                               
+                               $p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
+                               $p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
+                               
+                               $racoonconf .= <<<EOD
+sainfo address {$sa}/{$sn} any address {$tunnel['remote-subnet']} any \{
+       encryption_algorithm {$p2ealgos};
+       authentication_algorithm {$p2halgos};
+       compression_algorithm deflate;
+
+EOD;
+
+                               if ($tunnel['p2']['pfsgroup'])
+                                       $racoonconf .= "        pfs_group {$tunnel['p2']['pfsgroup']};\n";
+                                       
+                               if ($tunnel['p2']['lifetime'])
+                                       $racoonconf .= "        lifetime time {$tunnel['p2']['lifetime']} secs;\n";
+                                       
+                               $racoonconf .= "}\n\n";
+                       }
+                       
+                       /* mobile clients? */
+                       if (isset($ipseccfg['mobileclients']['enable'])) {
+                               
+                               $tunnel = $ipseccfg['mobileclients'];
+                               
+                               if (isset($tunnel['p1']['myident']['myaddress'])) {
+                                       $myidentt = "address";
+                                       $myident = $curwanip;
+                               } else if (isset($tunnel['p1']['myident']['address'])) {
+                                       $myidentt = "address";
+                                       $myident = $tunnel['p1']['myident']['address'];
+                               } else if (isset($tunnel['p1']['myident']['fqdn'])) {
+                                       $myidentt = "fqdn";
+                                       $myident = $tunnel['p1']['myident']['fqdn'];
+                               }
+                       
+                               $racoonconf .= <<<EOD
+remote anonymous \{
+       exchange_mode {$tunnel['p1']['mode']};
+       my_identifier {$myidentt} "{$myident}";
+       initial_contact on;
+       passive on;
+       generate_policy on;
+       support_proxy on;
+       proposal_check obey;
+       proposal \{
+               encryption_algorithm {$tunnel['p1']['encryption-algorithm']};
+               hash_algorithm {$tunnel['p1']['hash-algorithm']};
+               authentication_method pre_shared_key;
+               dh_group {$tunnel['p1']['dhgroup']};
+
+EOD;
+                               if ($tunnel['p1']['lifetime'])
+                                       $racoonconf .= "                lifetime time {$tunnel['p1']['lifetime']} secs;\n";
+                               
+                               $racoonconf .= "        }\n";
+                               
+                               if ($tunnel['p1']['lifetime'])
+                                       $racoonconf .= "        lifetime time {$tunnel['p1']['lifetime']} secs;\n";
+                                       
+                               $racoonconf .= "}\n\n";
+                               
+                               $p2ealgos = join(",", $tunnel['p2']['encryption-algorithm-option']);
+                               $p2halgos = join(",", $tunnel['p2']['hash-algorithm-option']);
+                               
+                               $racoonconf .= <<<EOD
+sainfo anonymous \{
+       encryption_algorithm {$p2ealgos};
+       authentication_algorithm {$p2halgos};
+       compression_algorithm deflate;
+
+EOD;
+
+                               if ($tunnel['p2']['pfsgroup'])
+                                       $racoonconf .= "        pfs_group {$tunnel['p2']['pfsgroup']};\n";
+                                       
+                               if ($tunnel['p2']['lifetime'])
+                                       $racoonconf .= "        lifetime time {$tunnel['p2']['lifetime']} secs;\n";
+                                       
+                               $racoonconf .= "}\n\n";
+                       }
+                       
+                       fwrite($fd, $racoonconf);
+                       fclose($fd);
+                       
+                       /* generate psk.txt */
+                       $fd = fopen("{$g['varetc_path']}/psk.txt", "w");
+                       if (!$fd) {
+                               printf("Error: cannot open psk.txt in vpn_ipsec_configure().\n");
+                               return 1;
+                       }
+                       
+                       $pskconf = "";
+                       
+                       if (is_array($ipseccfg['tunnel'])) {
+                               foreach ($ipseccfg['tunnel'] as $tunnel) {
+                                       if (isset($tunnel['disabled']))
+                                               continue;
+                                       $pskconf .= "{$tunnel['remote-gateway']}         {$tunnel['p1']['pre-shared-key']}\n";
+                               }
+                       }
+                       
+                       /* add PSKs for mobile clients */
+                       if (is_array($ipseccfg['mobilekey'])) {
+                               foreach ($ipseccfg['mobilekey'] as $key) {
+                                       $pskconf .= "{$key['ident']}    {$key['pre-shared-key']}\n";
+                               }
+                       }
+                       
+                       fwrite($fd, $pskconf);
+                       fclose($fd);
+                       chmod("{$g['varetc_path']}/psk.txt", 0600);
+                       
+                       /* start racoon */
+                       mwexec("/usr/local/sbin/racoon -d -f {$g['varetc_path']}/racoon.conf");
+               }
+       }
+       
+       /* write current WAN IP to file */
+       $fd = fopen("{$g['vardb_path']}/ipsec.wanip", "w");
+       if ($fd) {
+               fwrite($fd, $curwanip);
+               fclose($fd);
+       }
+       
+       if (!$g['booting']) {
+               /* reload the filter */
+               filter_configure();
+       }
+       
+       if ($g['booting'])
+               echo "done\n";
+       
+       return 0;
+}
+
+function vpn_pptpd_configure() {
+       global $config, $g;
+       
+       $syscfg = $config['system'];
+       $pptpdcfg = $config['pptpd'];
+       
+       if ($g['booting']) {
+               if (!$pptpdcfg['mode'] || ($pptpdcfg['mode'] == "off"))
+                       return 0;
+               
+               echo "Configuring PPTP VPN service... ";
+       } else {        
+               /* kill mpd */
+               killbypid("{$g['varrun_path']}/mpd-vpn.pid");
+               
+               /* wait for process to die */
+               sleep(2);
+               
+               /* remove mpd.conf, if it exists */
+               unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.conf");
+               unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.links");
+               unlink_if_exists("{$g['varetc_path']}/mpd-vpn/mpd.secret");
+       }
+               
+       /* make sure mpd-vpn directory exists */
+       if (!file_exists("{$g['varetc_path']}/mpd-vpn"))
+               mkdir("{$g['varetc_path']}/mpd-vpn");
+               
+       switch ($pptpdcfg['mode']) {
+               
+               case 'server':
+                       
+                       /* write mpd.conf */
+                       $fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.conf", "w");
+                       if (!$fd) {
+                               printf("Error: cannot open mpd.conf in vpn_pptpd_configure().\n");
+                               return 1;
+                       }
+                               
+                       $mpdconf = <<<EOD
+pptpd:
+
+EOD;
+
+                       for ($i = 0; $i < $g['n_pptp_units']; $i++) {
+                               $mpdconf .= "   load pptpc{$i}\n";
+                       }
+                       
+                       for ($i = 0; $i < $g['n_pptp_units']; $i++) {
+                       
+                               $clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
+                               $ngif = "ng" . ($i+1);
+                       
+                               $mpdconf .= <<<EOD
+
+pptpc{$i}:     
+       new -i {$ngif} pptpc{$i} pptpc{$i}
+       set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
+       load pptp_standard
+
+EOD;
+                       }
+                       
+                       $mpdconf .= <<<EOD
+
+pptp_standard:
+       set iface disable on-demand
+       set iface enable proxy-arp
+       set iface idle 1800
+       set iface up-script /usr/local/sbin/vpn-linkup
+       set bundle enable multilink
+       set bundle enable crypt-reqd
+       set link yes acfcomp protocomp
+       set link no pap chap
+       set link enable chap-msv2
+       set link mtu 1460
+       set link keep-alive 10 60
+       set ipcp yes vjcomp
+       set ipcp dns {$dnsconf}
+       set bundle enable compression
+       set ccp yes mppc
+       set ccp yes mpp-e128
+       set ccp yes mpp-stateless
+
+EOD;
+                       
+                       if (!isset($pptpdcfg['req128'])) {
+                               $mpdconf .= <<<EOD
+       set ccp yes mpp-e40
+       set ccp yes mpp-e56
+
+EOD;
+                       }
+                       
+                       if (isset($config['dnsmasq']['enable'])) {
+                               $mpdconf .= "   set ipcp dns " . $config['interfaces']['lan']['ipaddr'];
+                               if ($syscfg['dnsserver'][0])
+                                       $mpdconf .= " " . $syscfg['dnsserver'][0];
+                               $mpdconf .= "\n";
+                       } else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
+                               $mpdconf .= "   set ipcp dns " . join(" ", $syscfg['dnsserver']) . "\n";
+                       }
+                       
+                       if (isset($pptpdcfg['radius']['enable'])) {
+                               $mpdconf .= <<<EOD
+       set radius server {$pptpdcfg['radius']['server']} "{$pptpdcfg['radius']['secret']}"
+       set radius retries 3
+       set radius timeout 10
+       set bundle enable radius-auth
+       set bundle disable radius-fallback
+
+EOD;
+                       }
+
+                       fwrite($fd, $mpdconf);
+                       fclose($fd);
+                       
+                       /* write mpd.links */
+                       $fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.links", "w");
+                       if (!$fd) {
+                               printf("Error: cannot open mpd.links in vpn_pptpd_configure().\n");
+                               return 1;
+                       }
+                       
+                       $mpdlinks = "";
+                       
+                       for ($i = 0; $i < $g['n_pptp_units']; $i++) {
+                               $mpdlinks .= <<<EOD
+                       
+pptpc{$i}:
+       set link type pptp
+       set pptp enable incoming
+       set pptp disable originate
+       set pptp self 127.0.0.1
+
+EOD;
+                       }
+
+                       fwrite($fd, $mpdlinks);
+                       fclose($fd);
+                       
+                       /* write mpd.secret */
+                       $fd = fopen("{$g['varetc_path']}/mpd-vpn/mpd.secret", "w");
+                       if (!$fd) {
+                               printf("Error: cannot open mpd.secret in vpn_pptpd_configure().\n");
+                               return 1;
+                       }
+                       
+                       $mpdsecret = "";
+                       
+                       if (is_array($pptpdcfg['user'])) {
+                               foreach ($pptpdcfg['user'] as $user)
+                                       $mpdsecret .= "{$user['name']} \"{$user['password']}\"\n";
+                       }
+
+                       fwrite($fd, $mpdsecret);
+                       fclose($fd);
+                       chmod("{$g['varetc_path']}/mpd-vpn/mpd.secret", 0600);
+                       
+                       /* fire up mpd */
+                       mwexec("/usr/local/sbin/mpd -b -d {$g['varetc_path']}/mpd-vpn -p {$g['varrun_path']}/mpd-vpn.pid pptpd");
+                       
+                       break;
+                       
+               case 'redir':
+                       break;
+       }
+       
+       if (!$g['booting']) {
+               /* reload the filter */
+               filter_configure();
+       }
+       
+       if ($g['booting'])
+               echo "done\n";
+       
+       return 0;
+}
+
+function vpn_localnet_determine($adr, &$sa, &$sn) {
+       global $config, $g;
+
+       if (isset($adr)) {
+               if ($adr['network']) {                  
+                       switch ($adr['network']) {
+                               case 'lan':
+                                       $sn = $config['interfaces']['lan']['subnet'];
+                                       $sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
+                                       break;
+                       }
+               } else if ($adr['address']) {
+                       list($sa,$sn) = explode("/", $adr['address']);
+                       if (!$sn)
+                               $sn = 32;
+               }
+       } else {
+               $sn = $config['interfaces']['lan']['subnet'];
+               $sa = gen_subnet($config['interfaces']['lan']['ipaddr'], $sn);
+       }
+}
+
+function vpn_endpoint_determine($tunnel, $curwanip) {
+       
+       global $g, $config;
+       
+       if ((!$tunnel['interface']) || ($tunnel['interface'] == "wan")) {
+               if ($curwanip)
+                       return $curwanip;
+               else
+                       return null;
+       } else if ($tunnel['interface'] == "lan") {
+               return $config['interfaces']['lan']['ipaddr'];
+       } else {
+               $oc = $config['interfaces'][$tunnel['interface']];
+               
+               if (isset($oc['enable']) && $oc['if']) {
+                       return $oc['ipaddr'];
+               }
+       }
+       
+       return null;
+}
+       
+?>
diff --git a/phpconf/inc/xmlparse.inc b/phpconf/inc/xmlparse.inc
new file mode 100644 (file)
index 0000000..40edd38
--- /dev/null
@@ -0,0 +1,202 @@
+<?php
+/*
+       xmlparse.inc
+       functions to parse/dump configuration files in XML format
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* tags that are always to be handled as lists */
+$listtags = explode(" ", "rule user key dnsserver winsserver encryption-algorithm-option hash-algorithm-option hosts tunnel onetoone staticmap route alias pipe queue shellcmd mobilekey servernat proxyarpnet");
+
+function startElement($parser, $name, $attrs) {
+       global $depth, $curpath, $config, $havedata, $listtags;
+       
+       array_push($curpath, strtolower($name));
+       
+       $ptr =& $config;
+       foreach ($curpath as $path) {
+               $ptr =& $ptr[$path];
+       }
+       
+       /* is it an element that belongs to a list? */
+       if (in_array(strtolower($name), $listtags)) {
+       
+               /* is there an array already? */
+               if (!is_array($ptr)) {
+                       /* make an array */
+                       $ptr = array();
+               }
+               
+               array_push($curpath, count($ptr));
+               
+       } else if (isset($ptr)) {
+               /* multiple entries not allowed for this element, bail out */
+               die(sprintf("XML error: %s at line %d cannot occur more than once\n",
+                               $name,
+                               xml_get_current_line_number($parser)));
+       }
+       
+       $depth++;
+       $havedata = $depth;
+}
+
+function endElement($parser, $name) {
+       global $depth, $curpath, $config, $havedata, $listtags;
+       
+       if ($havedata == $depth) {
+               $ptr =& $config;
+               foreach ($curpath as $path) {
+                       $ptr =& $ptr[$path];
+               }
+               $ptr = "";
+       }
+       
+       array_pop($curpath);
+
+       if (in_array(strtolower($name), $listtags))
+               array_pop($curpath);
+       
+       $depth--;
+}
+
+function cData($parser, $data) {
+       global $depth, $curpath, $config, $havedata;
+       
+       $data = trim($data, "\t\n\r");
+       
+       if ($data != "") {
+               $ptr =& $config;
+               foreach ($curpath as $path) {
+                       $ptr =& $ptr[$path];
+               }
+
+               if (is_string($ptr)) {
+                       $ptr .= $data;
+               } else {
+                       if (trim($data, " ") != "") {
+                               $ptr = $data;
+                               $havedata++;
+                       }
+               }
+       }
+}
+
+function parse_xml_config($cffile, $rootobj) {
+
+       global $depth, $curpath, $config, $havedata, $listtags;
+
+       $config = array();
+       $curpath = array();
+       $depth = 0;
+       $havedata = 0;
+       
+       $xml_parser = xml_parser_create();
+       
+       xml_set_element_handler($xml_parser, "startElement", "endElement");
+       xml_set_character_data_handler($xml_parser, "cdata");
+       
+       if (!($fp = fopen($cffile, "r"))) {
+               die("Error: could not open XML input\n");
+       }
+       
+       while ($data = fread($fp, 4096)) {
+               if (!xml_parse($xml_parser, $data, feof($fp))) {
+                       die(sprintf("XML error: %s at line %d\n",
+                                               xml_error_string(xml_get_error_code($xml_parser)),
+                                               xml_get_current_line_number($xml_parser)));
+               }
+       }
+       xml_parser_free($xml_parser);
+       
+       if (!$config[$rootobj]) {
+               die("XML error: no $rootobj object found!\n");
+       }
+       
+       return $config[$rootobj];
+}
+
+function dump_xml_config_sub($arr, $indent) {
+
+       global $listtags;
+       
+       $xmlconfig = "";
+
+       foreach ($arr as $ent => $val) {
+               if (is_array($val)) {
+                       /* is it just a list of multiple values? */
+                       if (in_array(strtolower($ent), $listtags)) {
+                               foreach ($val as $cval) {
+                                       if (is_array($cval)) {
+                                               $xmlconfig .= str_repeat("\t", $indent);
+                                               $xmlconfig .= "<$ent>\n";
+                                               $xmlconfig .= dump_xml_config_sub($cval, $indent + 1);
+                                               $xmlconfig .= str_repeat("\t", $indent);
+                                               $xmlconfig .= "</$ent>\n";
+                                       } else {
+                                               $xmlconfig .= str_repeat("\t", $indent);
+                                               if ((is_bool($cval) && ($cval == true)) ||
+                                                       ($cval === ""))
+                                                       $xmlconfig .= "<$ent/>\n";
+                                               else if (!is_bool($cval))
+                                                       $xmlconfig .= "<$ent>" . htmlspecialchars($cval) . "</$ent>\n";
+                                       }
+                               }
+                       } else {
+                               /* it's an array */
+                               $xmlconfig .= str_repeat("\t", $indent);
+                               $xmlconfig .= "<$ent>\n";
+                               $xmlconfig .= dump_xml_config_sub($val, $indent + 1);
+                               $xmlconfig .= str_repeat("\t", $indent);
+                               $xmlconfig .= "</$ent>\n";
+                       }
+               } else {
+                       if ((is_bool($val) && ($val == true)) || ($val === "")) {
+                               $xmlconfig .= str_repeat("\t", $indent);
+                               $xmlconfig .= "<$ent/>\n";
+                       } else if (!is_bool($val)) {
+                               $xmlconfig .= str_repeat("\t", $indent);
+                               $xmlconfig .= "<$ent>" . htmlspecialchars($val) . "</$ent>\n";
+                       }
+               }
+       }
+       
+       return $xmlconfig;
+}
+
+function dump_xml_config($arr, $rootobj) {
+
+       $xmlconfig = "<?xml version=\"1.0\"?" . ">\n";
+       $xmlconfig .= "<$rootobj>\n";
+               
+       $xmlconfig .= dump_xml_config_sub($arr, 1);
+       
+       $xmlconfig .= "</$rootobj>\n";
+       
+       return $xmlconfig;
+}
+
+?>
diff --git a/phpconf/rc.banner b/phpconf/rc.banner
new file mode 100644 (file)
index 0000000..bb0804f
--- /dev/null
@@ -0,0 +1,60 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.banner
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+
+       $version = chop(file_get_contents("{$g['etc_path']}/version"));
+       $buildtime = chop(file_get_contents("{$g['etc_path']}/version.buildtime"));
+       
+       echo <<<EOD
+
+
+*** This is m0n0wall, version {$version}
+    built on {$buildtime} for {$g['platform']}
+    Copyright (C) 2002-2004 by Manuel Kasper. All rights reserved.
+    Visit http://m0n0.ch/wall for updates.
+    
+    
+    LAN IP address: {$config['interfaces']['lan']['ipaddr']}
+    
+    Port configuration:
+    
+    LAN   -> {$config['interfaces']['lan']['if']}
+    WAN   -> {$config['interfaces']['wan']['if']}
+
+EOD;
+
+       for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
+               echo "    OPT{$i}  -> {$config['interfaces']['opt' . $i]['if']} " .
+                       "({$config['interfaces']['opt' . $i]['descr']})\n";
+?>
diff --git a/phpconf/rc.bootup b/phpconf/rc.bootup
new file mode 100644 (file)
index 0000000..f7a7d60
--- /dev/null
@@ -0,0 +1,128 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.bootup
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       require_once("globals.inc");
+
+       /* let the other functions know we're booting */
+       $g['booting'] = TRUE;
+       touch("{$g['varrun_path']}/booting");
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+       
+       /* convert configuration, if necessary */
+       convert_config();
+       
+       /* set up our timezone */
+       system_timezone_configure();
+       
+       /* set up our hostname */
+       system_hostname_configure();
+       
+       /* make hosts file */
+       system_hosts_generate();
+       
+       /* generate resolv.conf */
+       system_resolvconf_generate();
+       
+       /* start pccardd */
+       system_pccard_start();
+       
+       /* establish ipfilter ruleset */
+       filter_configure();
+       
+       /* configure loopback interface */
+       interfaces_loopback_configure();
+       
+       /* set up LAN interface */
+       interfaces_lan_configure();
+       
+       /* set up WAN interface */
+       interfaces_wan_configure();
+       
+       /* set up Optional interfaces */
+       interfaces_optional_configure();
+       
+       /* resync ipfilter */
+       filter_resync();
+       
+       /* start ipmon */
+       filter_ipmon_start();
+       
+       /* set up static routes */
+       system_routing_configure();
+       
+       /* enable routing */
+       system_routing_enable();
+       
+       /* start syslogd */
+       system_syslogd_start();
+       
+       /* start web server */
+       system_webgui_start();
+       
+       /* configure console menu */
+       system_console_configure();
+       
+       /* start dnsmasq service */
+       services_dnsmasq_configure();
+       
+       /* start dyndns service */
+       services_dyndns_configure();
+       
+       /* start DHCP service */
+       services_dhcpd_configure();
+       
+       /* start SNMP service */
+       services_snmpd_configure();
+       
+       /* start proxy ARP service */
+       services_proxyarp_configure();
+
+       /* start the NTP client */
+       system_ntp_configure();
+       
+       /* start pptpd */
+       vpn_pptpd_configure();
+       
+       /* start traffic shaper */
+       shaper_configure();
+       
+       /* start IPsec tunnels */
+       vpn_ipsec_configure();
+       
+       /* run any shell commands specified in config.xml */
+       system_do_shell_commands();
+       
+       /* done */
+       unlink("{$g['varrun_path']}/booting");
+?>
diff --git a/phpconf/rc.initial.defaults b/phpconf/rc.initial.defaults
new file mode 100644 (file)
index 0000000..8e33fd2
--- /dev/null
@@ -0,0 +1,61 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.initial.defaults
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       /* don't parse the config so we can restore in case it's broken */
+       $noparseconfig = 1;
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+       
+       $fp = fopen('php://stdin', 'r');
+       
+       echo <<<EOD
+       
+You are about to reset the firewall to factory defaults.
+The firewall will reboot after resetting the configuration.
+
+Do you want to proceed? (y/n) 
+EOD;
+
+       if (strcasecmp(chop(fgets($fp)), "y") == 0) {
+               
+               reset_factory_defaults();
+               
+               echo <<<EOD
+
+The firewall is rebooting now.
+
+EOD;
+       
+               system_reboot_sync();
+       }
+?>
diff --git a/phpconf/rc.initial.password b/phpconf/rc.initial.password
new file mode 100644 (file)
index 0000000..7859e2c
--- /dev/null
@@ -0,0 +1,65 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.initial.password
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+       
+       $fp = fopen('php://stdin', 'r');
+       
+       echo <<<EOD
+       
+The webGUI password will be reset to the default (which is 'mono').
+
+Do you want to proceed? (y/n) 
+EOD;
+
+       if (strcasecmp(chop(fgets($fp)), "y") == 0) {
+       
+               $config['system']['password'] = crypt("mono");
+               
+               write_config();
+               system_password_configure();
+               
+               echo <<<EOD
+
+The password for the webGUI has been reset.
+
+Remember to set the password to something else than
+the default as soon as you have logged into the webGUI.
+
+Press ENTER to continue.
+
+EOD;
+       
+               fgets($fp);
+       }
+?>
diff --git a/phpconf/rc.initial.reboot b/phpconf/rc.initial.reboot
new file mode 100644 (file)
index 0000000..053d492
--- /dev/null
@@ -0,0 +1,55 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.initial.reboot
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+       
+       $fp = fopen('php://stdin', 'r');
+       
+       echo <<<EOD
+       
+The firewall will reboot. This may take one minute.
+
+Do you want to proceed? (y/n) 
+EOD;
+
+       if (strcasecmp(chop(fgets($fp)), "y") == 0) {
+               
+               echo <<<EOD
+
+The firewall is rebooting now.
+
+EOD;
+       
+               system_reboot_sync();
+       }
+?>
diff --git a/phpconf/rc.initial.setlanip b/phpconf/rc.initial.setlanip
new file mode 100644 (file)
index 0000000..08ca3f8
--- /dev/null
@@ -0,0 +1,112 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.initial.setlanip
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+       
+       $fp = fopen('php://stdin', 'r');
+       
+       do {
+               echo "\nEnter the new LAN IP address: ";
+               $lanip = chop(fgets($fp));
+               if ($lanip === "") {
+                       exit(0);
+               }
+       } while (!is_ipaddr($lanip));
+
+       echo "\nSubnet masks are entered as bit counts (as in CIDR notation) in m0n0wall.\n";
+       echo "e.g. 255.255.255.0 = 24\n";
+       echo "     255.255.0.0   = 16\n";
+       echo "     255.0.0.0     = 8\n\n";
+       
+       do {
+               echo "Enter the new LAN subnet bit count: ";
+               $lanbits = chop(fgets($fp));
+               if ($lanbits === "") {
+                       exit(0);
+               }
+       } while (!is_numeric($lanbits) || ($lanbits < 1) || ($lanbits > 31));
+       
+       $config['interfaces']['lan']['ipaddr'] = $lanip;
+       $config['interfaces']['lan']['subnet'] = $lanbits;
+       
+       echo "\nDo you want to enable the DHCP server on LAN? (y/n) ";
+       
+       if (strcasecmp(chop(fgets($fp)), "y") == 0) {
+               do {
+                       echo "Enter the start address of the client address range: ";
+                       $dhcpstartip = chop(fgets($fp));
+                       if ($dhcpstartip === "") {
+                               exit(0);
+                       }
+               } while (!is_ipaddr($dhcpstartip));
+               
+               do {
+                       echo "Enter the end address of the client address range: ";
+                       $dhcpendip = chop(fgets($fp));
+                       if ($dhcpendip === "") {
+                               exit(0);
+                       }
+               } while (!is_ipaddr($dhcpendip));
+               
+               $config['dhcpd']['lan']['enable'] = true;
+               $config['dhcpd']['lan']['range']['from'] = $dhcpstartip;
+               $config['dhcpd']['lan']['range']['to'] = $dhcpendip;
+       } else {
+               unset($config['dhcpd']['lan']['enable']);
+       }
+       
+       if ($config['system']['webgui']['protocol'] == "https") {
+       
+               echo "\nDo you want to revert to HTTP as the webGUI protocol? (y/n) ";
+               
+               if (strcasecmp(chop(fgets($fp)), "y") == 0)
+                       $config['system']['webgui']['protocol'] = "http";
+       }
+       
+       write_config();
+       interfaces_lan_configure();
+       
+       echo <<<EOD
+       
+The LAN IP address has been set to $lanip/$lanbits.
+You can now access the webGUI by opening the following URL
+in your browser:
+
+http://$lanip/
+
+Press ENTER to continue.
+
+EOD;
+
+       fgets($fp);
+?>
diff --git a/phpconf/rc.initial.setports b/phpconf/rc.initial.setports
new file mode 100644 (file)
index 0000000..d2d54ce
--- /dev/null
@@ -0,0 +1,231 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.initial.setports
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+       
+       $fp = fopen('php://stdin', 'r');
+       
+       $iflist = get_interface_list();
+       
+       echo <<<EOD
+
+Valid interfaces are:
+
+
+EOD;
+
+       foreach ($iflist as $iface => $ifa) {
+               echo sprintf("% -8s%s%s\n", $iface, $ifa['mac'],
+                       $ifa['up'] ? "   (up)" : "");
+       }
+       
+       echo <<<EOD
+
+If you don't know the names of your interfaces, you may choose to use
+auto-detection. In that case, disconnect all interfaces before you begin,
+and reconnect each one when prompted to do so.
+
+EOD;
+       
+       do {
+               echo "\nEnter the LAN interface name or 'a' for auto-detection: ";
+               $lanif = chop(fgets($fp));
+               if ($lanif === "") {
+                       exit(0);
+               }
+               
+               if ($lanif === "a")
+                       $lanif = autodetect_interface("LAN", $fp);
+               else if (!array_key_exists($lanif, $iflist)) {
+                       echo "\nInvalid interface name '{$lanif}'\n";
+                       unset($lanif);
+                       continue;
+               }
+       } while (!$lanif);
+       
+       do {
+               echo "\nEnter the WAN interface name or 'a' for auto-detection: ";
+               $wanif = chop(fgets($fp));
+               if ($wanif === "") {
+                       exit(0);
+               }
+               if ($wanif === "a")
+                       $wanif = autodetect_interface("WAN", $fp);
+               else if (!array_key_exists($wanif, $iflist)) {
+                       echo "\nInvalid interface name '{$wanif}'\n";
+                       unset($wanif);
+                       continue;
+               }
+       } while (!$wanif);
+       
+       /* optional interfaces */
+       $i = 0;
+       $optif = array();
+       
+       while (1) {
+               if ($optif[$i])
+                       $i++;
+               $i1 = $i + 1;
+               echo "\nEnter the Optional {$i1} interface name or 'a' for auto-detection\n" .
+                       "(or nothing if finished): ";
+               $optif[$i] = chop(fgets($fp));
+               
+               if ($optif[$i]) {
+                       if ($optif[$i] === "a") {
+                               $ad = autodetect_interface("Optional " . $i1, $fp);
+                               if ($ad)
+                                       $optif[$i] = $ad;
+                               else
+                                       unset($optif[$i]);
+                       } else if (!array_key_exists($optif[$i], $iflist)) {
+                               echo "\nInvalid interface name '{$optif[$i]}'\n";
+                               unset($optif[$i]);
+                               continue;
+                       }
+               } else {
+                       unset($optif[$i]);
+                       break;
+               }
+       }
+       
+       /* check for double assignments */
+       $ifarr = array_merge(array($lanif, $wanif), $optif);
+       
+       for ($i = 0; $i < (count($ifarr)-1); $i++) {
+               for ($j = ($i+1); $j < count($ifarr); $j++) {
+                       if ($ifarr[$i] == $ifarr[$j]) {
+                               echo <<<EOD
+       
+Error: you can't assign the same interface name twice!
+
+EOD;
+
+                               exit(0);
+                       }
+               }
+       }
+       
+       echo <<<EOD
+       
+The interfaces will be assigned as follows:
+
+LAN  -> {$lanif}
+WAN  -> {$wanif}
+
+EOD;
+
+       for ($i = 0; $i < count($optif); $i++) {
+               echo "OPT" . ($i+1) . " -> " . $optif[$i] . "\n";
+       }
+
+echo <<<EOD
+
+The firewall will reboot after saving the changes.
+
+Do you want to proceed? (y/n) 
+EOD;
+       
+       if (strcasecmp(chop(fgets($fp)), "y") == 0) {
+       
+               $config['interfaces']['lan']['if'] = $lanif;
+               if (preg_match("/^(wi|awi|an)/", $lanif)) {
+                       if (!is_array($config['interfaces']['lan']['wireless']))
+                               $config['interfaces']['lan']['wireless'] = array();
+               } else {
+                       unset($config['interfaces']['lan']['wireless']);
+               }
+               
+               $config['interfaces']['wan']['if'] = $wanif;
+               if (preg_match("/^(wi|awi|an)/", $wanif)) {
+                       if (!is_array($config['interfaces']['wan']['wireless']))
+                               $config['interfaces']['wan']['wireless'] = array();
+               } else {
+                       unset($config['interfaces']['wan']['wireless']);
+               }
+               
+               for ($i = 0; $i < count($optif); $i++) {
+                       if (!is_array($config['interfaces']['opt' . ($i+1)]))
+                               $config['interfaces']['opt' . ($i+1)] = array();
+                       
+                       $config['interfaces']['opt' . ($i+1)]['if'] = $optif[$i];
+                       
+                       /* wireless interface? */
+                       if (preg_match("/^(wi|awi|an)/", $optif[$i])) {
+                               if (!is_array($config['interfaces']['opt' . ($i+1)]['wireless']))
+                                       $config['interfaces']['opt' . ($i+1)]['wireless'] = array();
+                       } else {
+                               unset($config['interfaces']['opt' . ($i+1)]['wireless']);
+                       }
+                       
+                       unset($config['interfaces']['opt' . ($i+1)]['enable']);
+                       $config['interfaces']['opt' . ($i+1)]['descr'] = "OPT" . ($i+1);
+               }
+               
+               /* remove all other (old) optional interfaces */
+               for (; isset($config['interfaces']['opt' . ($i+1)]); $i++)
+                       unset($config['interfaces']['opt' . ($i+1)]);
+               
+               write_config();
+               
+               echo <<<EOD
+
+The firewall is rebooting now.
+
+EOD;
+       
+               system_reboot_sync();
+       }
+       
+       function autodetect_interface($ifname, $fp) {
+               $iflist_prev = get_interface_list();
+               echo <<<EOD
+
+Connect the {$ifname} interface now and make sure that the link is up.
+Then press ENTER to continue.
+
+EOD;
+               fgets($fp);
+               $iflist = get_interface_list();
+               
+               foreach ($iflist_prev as $ifn => $ifa) {
+                       if (!$ifa['up'] && $iflist[$ifn]['up']) {
+                               echo "Detected link-up on interface {$ifn}.\n";
+                               return $ifn;
+                       }
+               }
+               
+               echo "No link-up detected.\n";
+               
+               return null;
+       }
+?>
diff --git a/phpconf/rc.newwanip b/phpconf/rc.newwanip
new file mode 100644 (file)
index 0000000..e99059a
--- /dev/null
@@ -0,0 +1,52 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+       rc.newwanip
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+       /* parse the configuration and include all functions used below */
+       require_once("config.inc");
+       require_once("functions.inc");
+       
+       /* WAN IP address has changed */
+       
+       /* make sure to wait until the boot scripts have finished */
+       while (file_exists("{$g['varrun_path']}/booting")) {
+               sleep(1);
+       }
+       
+       /* resync ipfilter */
+       filter_resync();
+       
+       /* reconfigure IPsec tunnels */
+       vpn_ipsec_configure(true);
+       
+       /* regenerate resolv.conf if DNS overrides are allowed */
+       if (isset($config['system']['dnsallowoverride']))
+               system_resolvconf_generate(true);
+?>
diff --git a/webgui/block.gif b/webgui/block.gif
new file mode 100644 (file)
index 0000000..df95240
Binary files /dev/null and b/webgui/block.gif differ
diff --git a/webgui/block_d.gif b/webgui/block_d.gif
new file mode 100644 (file)
index 0000000..2d3d980
Binary files /dev/null and b/webgui/block_d.gif differ
diff --git a/webgui/check.gif b/webgui/check.gif
new file mode 100644 (file)
index 0000000..09a979a
Binary files /dev/null and b/webgui/check.gif differ
diff --git a/webgui/diag_backup.php b/webgui/diag_backup.php
new file mode 100644 (file)
index 0000000..cdeda0a
--- /dev/null
@@ -0,0 +1,122 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_backup.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* omit no-cache headers because it confuses IE with file downloads */
+$omit_nocacheheaders = true;
+require("guiconfig.inc"); 
+
+if ($_POST) {
+
+       unset($input_errors);
+       
+       if (stristr($_POST['Submit'], "Restore"))
+               $mode = "restore";
+       else if (stristr($_POST['Submit'], "Download"))
+               $mode = "download";
+               
+       if ($mode) {
+               if ($mode == "download") {
+                       config_lock();
+                       $fs = filesize($g['conf_path'] . "/config.xml");
+                       header("Content-Type: application/octet-stream"); 
+                       header("Content-Disposition: attachment; filename=config.xml");
+                       header("Content-Length: $fs");
+                       readfile($g['conf_path'] . "/config.xml");
+                       config_unlock();
+                       exit;
+               } else if ($mode == "restore") {
+                       if (is_uploaded_file($_FILES['conffile']['tmp_name'])) {
+                               if (config_install($_FILES['conffile']['tmp_name']) == 0) {
+                                       system_reboot();
+                                       $savemsg = "The configuration has been restored. The firewall is now rebooting.";
+                               } else {
+                                       $input_errors[] = "The configuration could not be restored.";
+                               }
+                       } else {
+                               $input_errors[] = "The configuration could not be restored (file upload error).";
+                       }
+               }
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: Backup/restore</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+      <p class="pgtitle">Diagnostics: Backup/restore</p>
+            <?php if ($input_errors) print_input_errors($input_errors); ?>
+            <?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+            <form action="diag_backup.php" method="post" enctype="multipart/form-data">
+              <table width="100%" border="0" cellspacing="0" cellpadding="0">
+                <tr> 
+                  <td colspan="2" class="listtopic">Backup configuration</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="baseline">&nbsp;</td>
+                  <td width="78%" class="listn"> 
+                    <p> Click this button to download the system configuration 
+                      in XML format.<br>
+                      <br>
+                      <input name="Submit" type="submit" class="formbtn" id="download" value="Download configuration">
+                      <br>
+                      &nbsp; <br>
+                      &nbsp; </p></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" class="listtopic">Restore configuration</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="baseline">&nbsp;</td>
+                  <td width="78%" class="listn"> 
+                    <p> Open a m0n0wall configuration XML file and click the button 
+                      below to restore the configuration.<br>
+                      <br>
+                      <strong><span class="red">Note:</span></strong><br>
+                      The firewall will reboot after restoring the configuration.<br>
+                      <br>
+                      <input name="conffile" type="file" class="formfld" id="conffile" size="40">
+                      <br>
+                      <br>
+                      <input name="Submit" type="submit" class="formbtn" id="restore" value="Restore configuration">
+                    </p>
+                    </td>
+                </tr>
+              </table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_defaults.php b/webgui/diag_defaults.php
new file mode 100644 (file)
index 0000000..b47c7ff
--- /dev/null
@@ -0,0 +1,73 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_defaults.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if ($_POST) {
+       if ($_POST['Submit'] != " No ") {
+               reset_factory_defaults();
+               system_reboot();
+               $rebootmsg = "The system has been reset to factory defaults and is now rebooting. This may take one minute.";
+       } else {
+               header("Location: index.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: Factory defaults</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: Factory defaults</p>
+<?php if ($rebootmsg): echo print_info_box(htmlspecialchars($rebootmsg)); else: ?>
+      <form action="diag_defaults.php" method="post">
+              <p><strong>If you click &quot;Yes&quot;, the firewall will be reset 
+                to factory defaults and will reboot immediately. The entire system 
+                configuration will be overwritten. The LAN IP address will be 
+                reset to 192.168.1.1, the system will be configured as a DHCP 
+                server, and the password will be set to 'mono'.<br>
+                <br>
+                Are you sure you want to proceed?</strong></p>
+        <p> 
+          <input name="Submit" type="submit" class="formbtn" value=" Yes ">
+          <input name="Submit" type="submit" class="formbtn" value=" No ">
+        </p>
+      </form>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_dhcp_leases.php b/webgui/diag_dhcp_leases.php
new file mode 100644 (file)
index 0000000..58a7d55
--- /dev/null
@@ -0,0 +1,189 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_dhcp_leases.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Björn Pålsson <bjorn@networksab.com> and Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: DHCP leases</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: DHCP leases</p>
+<?php
+
+flush();
+
+function leasecmp($a, $b) {
+       return strcmp($a[$_GET['order']], $b[$_GET['order']]);
+}
+
+$fp = @fopen("{$g['vardb_path']}/dhcpd.leases","r");
+
+if ($fp):
+
+$return = array();
+
+while ($line = fgets($fp)) {
+       $matches = "";
+
+       // Sort out comments
+       // C-style comments not supported!
+       if (preg_match("/^\s*[\r|\n]/", $line, $matches[0]) ||
+                               preg_match("/^([^\"#]*)#.*$/", $line, $matches[1]) ||
+                               preg_match("/^([^\"]*)\/\/.*$/", $line, $matches[2]) ||
+                               preg_match("/\s*#(.*)/", $line, $matches[3]) ||
+                               preg_match("/\\\"\176/", $line, $matches[4])
+               ) {
+               $line = "";
+               continue;
+       }
+
+       if (preg_match("/(.*)#(.*)/", $line, $matches))
+               $line = $matches[0];
+
+       // Tokenize lines
+       do {
+               if (preg_match("/^\s*\"([^\"]*)\"(.*)$/", $line, $matches)) {
+                       $line = $matches[2];
+                       $return[] = array($matches[1], 0);
+               } else if (preg_match("/^\s*([{};])(.*)$/", $line, $matches)) {
+                       $line = $matches[2];
+                       $return[] = array($matches[0], 1);
+               } else if (preg_match("/^\s*([^{}; \t]+)(.*)$/", $line, $matches)) {
+                       $line = $matches[2];
+                       $return[] = array($matches[1], 0);
+               } else
+                       break;
+
+       } while($line);
+
+       $lines++;
+}
+
+fclose($fp);
+
+$leases = array();
+$i = 0;
+
+// Put everything together again
+while ($data = array_shift($return)) {
+       if ($data[0] == "next") {
+               $d = array_shift($return);
+       }
+       if ($data[0] == "lease") {
+               $d = array_shift($return);
+               $leases[$i]['ip'] = $d[0];
+       }
+       if ($data[0] == "client-hostname") {
+               $d = array_shift($return);
+               $leases[$i]['hostname'] = $d[0];
+       }
+       if ($data[0] == "hardware") {
+               $d = array_shift($return);
+               if ($d[0] == "ethernet") {
+                       $d = array_shift($return);
+                       $leases[$i]['mac'] = $d[0];
+               }
+       } else if ($data[0] == "starts") {
+               $d = array_shift($return);
+               $d = array_shift($return);
+               $leases[$i]['start'] = $d[0];
+               $d = array_shift($return);
+               $leases[$i]['start'] .= " " . $d[0];
+       } else if ($data[0] == "ends") {
+               $d = array_shift($return);
+               $d = array_shift($return);
+               $leases[$i]['end'] = $d[0];
+               $d = array_shift($return);
+               $leases[$i]['end'] .= " " . $d[0];
+       } else if ($data[0] == "binding") {
+               $d = array_shift($return);
+               if ($d[0] == "state") {
+                       $d = array_shift($return);
+                       $leases[$i]['act'] = $d[0];
+               }
+       } else if (($data[0] == "}") && ($data[1] == 1))                // End of group
+               $i++;
+}
+
+if ($_GET['order'])
+       usort($leases, "leasecmp");
+?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr>
+    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=ip">IP address</a></td>
+    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=mac">MAC address</a></td>
+    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=hostname">Hostname</a></td>
+    <td class="listhdrr"><a href="?all=<?=$_GET['all'];?>&order=start">Start</a></td>
+    <td class="listhdr"><a href="?all=<?=$_GET['all'];?>&order=end">End</a></td>
+       </tr>
+<?php
+foreach ($leases as $data) {
+       if (($data['act'] == "active") || ($_GET['all'] == 1)) {
+               if ($data['act'] != "active") {
+                       $fspans = "<span class=\"gray\">";
+                       $fspane = "</span>";
+               } else {
+                       $fspans = $fspane = "";
+               }
+               echo "<tr>\n";
+               echo "<td class=\"listlr\">{$fspans}{$data['ip']}{$fspane}&nbsp;</td>\n";
+               echo "<td class=\"listr\">{$fspans}{$data['mac']}{$fspane}&nbsp;</td>\n";
+               echo "<td class=\"listr\">{$fspans}{$data['hostname']}{$fspane}&nbsp;</td>\n";
+               echo "<td class=\"listr\">{$fspans}{$data['start']}{$fspane}&nbsp;</td>\n";
+               echo "<td class=\"listr\">{$fspans}{$data['end']}{$fspane}&nbsp;</td>\n";
+               echo "</tr>\n";
+       }
+}
+?>
+</table>
+<p>
+<form action="diag_dhcp_leases.php" method="GET">
+<input type="hidden" name="order" value="<?=$_GET['order'];?>">
+<?php if ($_GET['all']): ?>
+<input type="hidden" name="all" value="0">
+<input type="submit" class="formbtn" value="Show active leases only">
+<?php else: ?>
+<input type="hidden" name="all" value="1">
+<input type="submit" class="formbtn" value="Show active and expired leases">
+<?php endif; ?>
+</form>
+<?php else: ?>
+<p><strong>No leases file found. Is the DHCP server active?</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_ipsec_sad.php b/webgui/diag_ipsec_sad.php
new file mode 100644 (file)
index 0000000..0930de9
--- /dev/null
@@ -0,0 +1,138 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_ipsec_sad.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: IPsec</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: IPsec</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabact">SAD</td>
+    <td nowrap class="tabinact"><a href="diag_ipsec_spd.php" class="tblnk">SPD</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="3" class="tabcont">
+<?php
+
+/* delete any SA? */
+if ($_GET['act'] == "del") {
+       $fd = @popen("/usr/sbin/setkey -c > /dev/null 2>&1", "w");
+       if ($fd) {
+               fwrite($fd, "delete {$_GET['src']} {$_GET['dst']} {$_GET['proto']} {$_GET['spi']} ;\n");
+               pclose($fd);
+               sleep(1);
+       }
+}
+
+/* query SAD */
+$fd = @popen("/usr/sbin/setkey -D", "r");
+$sad = array();
+if ($fd) {
+       while (!feof($fd)) {
+               $line = chop(fgets($fd));
+               if (!$line)
+                       continue;
+               if ($line == "No SAD entries.")
+                       break;
+               if ($line[0] != "\t") {
+                       if (is_array($cursa))
+                               $sad[] = $cursa;
+                       $cursa = array();
+                       list($cursa['src'],$cursa['dst']) = explode(" ", $line);
+                       $i = 0;
+               } else {
+                       $linea = explode(" ", trim($line));
+                       if ($i == 1) {
+                               $cursa['proto'] = $linea[0];
+                               $cursa['spi'] = substr($linea[2], strpos($linea[2], "x")+1, -1);
+                       } else if ($i == 2) {
+                               $cursa['ealgo'] = $linea[1];
+                       } else if ($i == 3) {
+                               $cursa['aalgo'] = $linea[1];
+                       }
+               }
+               $i++;
+       }
+       if (is_array($cursa) && count($cursa))
+               $sad[] = $cursa;
+       pclose($fd);
+}
+if (count($sad)):
+?>
+            <table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr>
+                <td nowrap class="listhdrr">Source</td>
+                <td nowrap class="listhdrr">Destination</a></td>
+                <td nowrap class="listhdrr">Protocol</td>
+                <td nowrap class="listhdrr">SPI</td>
+                <td nowrap class="listhdrr">Enc. alg.</td>
+                <td nowrap class="listhdr">Auth. alg.</td>
+                <td nowrap class="list"></td>
+       </tr>
+<?php
+foreach ($sad as $sa): ?>
+       <tr>
+               <td class="listlr"><?=htmlspecialchars($sa['src']);?></td>
+               <td class="listr"><?=htmlspecialchars($sa['dst']);?></td>
+               <td class="listr"><?=htmlspecialchars(strtoupper($sa['proto']));?></td>
+               <td class="listr"><?=htmlspecialchars($sa['spi']);?></td>
+               <td class="listr"><?=htmlspecialchars($sa['ealgo']);?></td>
+               <td class="listr"><?=htmlspecialchars($sa['aalgo']);?></td>
+               <td class="list" nowrap>
+               <?php
+                       $args = "src=" . rawurlencode($sa['src']);
+                       $args .= "&dst=" . rawurlencode($sa['dst']);
+                       $args .= "&proto=" . rawurlencode($sa['proto']);
+                       $args .= "&spi=" . rawurlencode("0x" . $sa['spi']);
+               ?>
+                 <a href="diag_ipsec_sad.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security association?')"><img src="x.gif" width="17" height="17" border="0"></a>
+               </td>
+                               
+       </tr>
+<?php endforeach; ?>
+</table>
+<?php else: ?>
+<p><strong>No IPsec security associations.</strong></p>
+<?php endif; ?>
+</td></tr></table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_ipsec_spd.php b/webgui/diag_ipsec_spd.php
new file mode 100644 (file)
index 0000000..1faeba7
--- /dev/null
@@ -0,0 +1,151 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_ipsec_spd.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: IPsec</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: IPsec</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="diag_ipsec_sad.php" class="tblnk">SAD</a></td>
+    <td nowrap class="tabact">SPD</td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="3" class="tabcont">
+<?php
+
+/* delete any SP? */
+if ($_GET['act'] == "del") {
+       $fd = @popen("/usr/sbin/setkey -c > /dev/null 2>&1", "w");
+       if ($fd) {
+               fwrite($fd, "spddelete {$_GET['src']} {$_GET['dst']} any -P {$_GET['dir']} ;\n");
+               pclose($fd);
+               sleep(1);
+       }
+}
+
+/* query SAD */
+$fd = @popen("/usr/sbin/setkey -DP", "r");
+$spd = array();
+if ($fd) {
+       while (!feof($fd)) {
+               $line = chop(fgets($fd));
+               if (!$line)
+                       continue;
+               if ($line == "No SPD entries.")
+                       break;
+               if ($line[0] != "\t") {
+                       if (is_array($cursp))
+                               $spd[] = $cursp;
+                       $cursp = array();
+                       $linea = explode(" ", $line);
+                       $cursp['src'] = substr($linea[0], 0, strpos($linea[0], "["));
+                       $cursp['dst'] = substr($linea[1], 0, strpos($linea[1], "["));
+                       $i = 0;
+               } else {
+                       $linea = explode(" ", trim($line));
+                       if ($i == 1) {
+                               $cursp['dir'] = $linea[0];
+                       } else if ($i == 2) {
+                               $upperspec = explode("/", $linea[0]);
+                               $cursp['proto'] = $upperspec[0];
+                               list($cursp['ep_src'], $cursp['ep_dst']) = explode("-", $upperspec[2]);
+                       }
+               }
+               $i++;
+       }
+       if (is_array($cursp) && count($cursp))
+               $spd[] = $cursp;
+       pclose($fd);
+}
+if (count($spd)):
+?>
+            <table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr>
+                <td nowrap class="listhdrr">Source</td>
+                <td nowrap class="listhdrr">Destination</a></td>
+                <td nowrap class="listhdrr">Direction</td>
+                <td nowrap class="listhdrr">Protocol</td>
+                <td nowrap class="listhdrr">Tunnel endpoints</td>
+                <td nowrap class="list"></td>
+       </tr>
+<?php
+foreach ($spd as $sp): ?>
+       <tr>
+               <td class="listlr" valign="top"><?=htmlspecialchars($sp['src']);?></td>
+               <td class="listr" valign="top"><?=htmlspecialchars($sp['dst']);?></td>
+               <td class="listr" valign="top"><img src="<?=$sp['dir'];?>.gif" width="11" height="11" style="margin-top: 2px"></td>
+               <td class="listr" valign="top"><?=htmlspecialchars(strtoupper($sp['proto']));?></td>
+               <td class="listr" valign="top"><?=htmlspecialchars($sp['ep_src']);?> - <br>
+                       <?=htmlspecialchars($sp['ep_dst']);?></td>
+               <td class="list" nowrap>
+               <?php
+                       $args = "src=" . rawurlencode($sp['src']);
+                       $args .= "&dst=" . rawurlencode($sp['dst']);
+                       $args .= "&dir=" . rawurlencode($sp['dir']);
+               ?>
+                 <a href="diag_ipsec_spd.php?act=del&<?=$args;?>" onclick="return confirm('Do you really want to delete this security policy?')"><img src="x.gif" width="17" height="17" border="0"></a>
+               </td>
+                               
+       </tr>
+<?php endforeach; ?>
+</table>
+<br>
+<table border="0" cellspacing="0" cellpadding="0">
+  <tr> 
+       <td width="16"><img src="in.gif" width="11" height="11"></td>
+       <td>incoming (as seen by firewall)</td>
+  </tr>
+  <tr> 
+       <td colspan="5" height="4"></td>
+  </tr>
+  <tr> 
+       <td><img src="out.gif" width="11" height="11"></td>
+       <td>outgoing (as seen by firewall)</td>
+  </tr>
+</table>
+<?php else: ?>
+<p><strong>No IPsec security policies.</strong></p>
+<?php endif; ?>
+</td></tr></table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_logs.php b/webgui/diag_logs.php
new file mode 100644 (file)
index 0000000..5c2bbb6
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_logs.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+       $nentries = 50;
+
+if ($_POST['clear']) {
+       exec("/usr/sbin/clog -i -s 262144 /var/log/system.log");
+}
+
+function dump_clog($logfile, $tail, $withorig = true) {
+       global $g, $config;
+
+       $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+       exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+       
+       foreach ($logarr as $logent) {
+               $logent = preg_split("/\s+/", $logent, 6);
+               echo "<tr valign=\"top\">\n";
+               
+               if ($withorig) {
+                       echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+                       echo "<td class=\"listr\">" . htmlspecialchars($logent[4] . " " . $logent[5]) . "</td>\n";
+               } else {
+                       echo "<td class=\"listlr\" colspan=\"2\">" . htmlspecialchars($logent[5]) . "</td>\n";
+               }
+               echo "</tr>\n";
+       }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: System logs</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabact">System</td>
+    <td nowrap class="tabinact"><a href="diag_logs_filter.php" class="tblnk">Firewall</a></td>
+    <td nowrap class="tabinact"><a href="diag_logs_dhcp.php" class="tblnk">DHCP</a></td>
+    <td nowrap class="tabinact"><a href="diag_logs_settings.php" class="tblnk">Settings</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+               <table width="100%" border="0" cellspacing="0" cellpadding="0">
+                 <tr> 
+                       <td colspan="2" class="listtopic"> 
+                         Last <?=$nentries;?> system log entries</td>
+                 </tr>
+                 <?php dump_clog("/var/log/system.log", $nentries); ?>
+               </table>
+               <br><form action="diag_logs.php" method="post">
+<input name="clear" type="submit" class="formbtn" value="Clear log">
+</form>
+       </td>
+  </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_logs_dhcp.php b/webgui/diag_logs_dhcp.php
new file mode 100644 (file)
index 0000000..64fb4cb
--- /dev/null
@@ -0,0 +1,101 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_logs_dhcp.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+       $nentries = 50;
+
+if ($_POST['clear']) {
+       exec("/usr/sbin/clog -i -s 32768 /var/log/dhcpd.log");
+}
+
+function dump_clog($logfile, $tail, $withorig = true) {
+       global $g, $config;
+
+       $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+       exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+       
+       foreach ($logarr as $logent) {
+               $logent = preg_split("/\s+/", $logent, 6);
+               echo "<tr valign=\"top\">\n";
+               
+               if ($withorig) {
+                       echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+                       echo "<td class=\"listr\">" . htmlspecialchars($logent[4] . " " . $logent[5]) . "</td>\n";
+               } else {
+                       echo "<td class=\"listlr\" colspan=\"2\">" . htmlspecialchars($logent[5]) . "</td>\n";
+               }
+               echo "</tr>\n";
+       }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: System logs</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="diag_logs.php" class="tblnk">System</a></td>
+    <td nowrap class="tabinact"><a href="diag_logs_filter.php" class="tblnk">Firewall</a></td>
+    <td nowrap class="tabact">DHCP</td>
+    <td nowrap class="tabinact"><a href="diag_logs_settings.php" class="tblnk">Settings</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+               <table width="100%" border="0" cellspacing="0" cellpadding="0">
+                 <tr> 
+                       <td colspan="2" class="listtopic"> 
+                         Last <?=$nentries;?> DHCP service log entries</td>
+                 </tr>
+                 <?php dump_clog("/var/log/dhcpd.log", $nentries); ?>
+               </table>
+               <br><form action="diag_logs_dhcp.php" method="post">
+<input name="clear" type="submit" class="formbtn" value="Clear log">
+</form>
+       </td>
+  </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
+
diff --git a/webgui/diag_logs_filter.php b/webgui/diag_logs_filter.php
new file mode 100644 (file)
index 0000000..5f8c733
--- /dev/null
@@ -0,0 +1,100 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_logs_filter.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$nentries = $config['syslog']['nentries'];
+if (!$nentries)
+       $nentries = 50;
+
+if ($_POST['clear']) {
+       exec("/usr/sbin/clog -i -s 262144 /var/log/filter.log");
+}
+
+function dump_clog($logfile, $tail, $withorig = true) {
+       global $g, $config;
+
+       $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+       exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+       
+       foreach ($logarr as $logent) {
+               $logent = preg_split("/\s+/", $logent, 6);
+               echo "<tr valign=\"top\">\n";
+               
+               if ($withorig) {
+                       echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+                       echo "<td class=\"listr\">" . htmlspecialchars($logent[4] . " " . $logent[5]) . "</td>\n";
+               } else {
+                       echo "<td class=\"listlr\" colspan=\"2\">" . htmlspecialchars($logent[5]) . "</td>\n";
+               }
+               echo "</tr>\n";
+       }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: System logs</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="diag_logs.php" class="tblnk">System</a></td>
+    <td nowrap class="tabact">Firewall</td>
+    <td nowrap class="tabinact"><a href="diag_logs_dhcp.php" class="tblnk">DHCP</td>
+    <td nowrap class="tabinact"><a href="diag_logs_settings.php" class="tblnk">Settings</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+               <table width="100%" border="0" cellspacing="0" cellpadding="0">
+                 <tr> 
+                       <td colspan="2" class="listtopic"> 
+                         Last <?=$nentries;?> firewall log entries</td>
+                 </tr>
+                 <?php dump_clog("/var/log/filter.log", $nentries, false); ?>
+               </table>
+               <br><form action="diag_logs_filter.php" method="post">
+<input name="clear" type="submit" class="formbtn" value="Clear log">
+</form>
+       </td>
+  </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_logs_settings.php b/webgui/diag_logs_settings.php
new file mode 100644 (file)
index 0000000..3a53e9f
--- /dev/null
@@ -0,0 +1,187 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_logs_settings.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['reverse'] = isset($config['syslog']['reverse']);
+$pconfig['nentries'] = $config['syslog']['nentries'];
+$pconfig['remoteserver'] = $config['syslog']['remoteserver'];
+$pconfig['filter'] = isset($config['syslog']['filter']);
+$pconfig['dhcp'] = isset($config['syslog']['dhcp']);
+$pconfig['system'] = isset($config['syslog']['system']);
+$pconfig['enable'] = isset($config['syslog']['enable']);
+$pconfig['logdefaultblock'] = !isset($config['syslog']['nologdefaultblock']);
+
+if (!$pconfig['nentries'])
+       $pconfig['nentries'] = 50;
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['enable'] && !is_ipaddr($_POST['remoteserver'])) {
+               $input_errors[] = "A valid IP address must be specified.";
+       }
+       if (($_POST['nentries'] < 5) || ($_POST['nentries'] > 1000)) {
+               $input_errors[] = "Number of log entries to show must be between 5 and 1000.";
+       }
+
+       if (!$input_errors) {
+               $config['syslog']['reverse'] = $_POST['reverse'] ? true : false;
+               $config['syslog']['nentries'] = (int)$_POST['nentries'];
+               $config['syslog']['remoteserver'] = $_POST['remoteserver'];
+               $config['syslog']['filter'] = $_POST['filter'] ? true : false;
+               $config['syslog']['dhcp'] = $_POST['dhcp'] ? true : false;
+               $config['syslog']['system'] = $_POST['system'] ? true : false;
+               $config['syslog']['enable'] = $_POST['enable'] ? true : false;
+               $oldnologdefaultblock = isset($config['syslog']['nologdefaultblock']);
+               $config['syslog']['nologdefaultblock'] = $_POST['logdefaultblock'] ? false : true;
+               
+               write_config();
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = system_syslogd_start();
+                       if ($oldnologdefaultblock !== isset($config['syslog']['nologdefaultblock']))
+                               $retval |= filter_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);       
+       }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: System logs</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+       if (document.iform.enable.checked || enable_over) {
+               document.iform.remoteserver.disabled = 0;
+               document.iform.filter.disabled = 0;
+               document.iform.dhcp.disabled = 0;
+               document.iform.system.disabled = 0;
+       } else {
+               document.iform.remoteserver.disabled = 1;
+               document.iform.filter.disabled = 1;
+               document.iform.dhcp.disabled = 1;
+               document.iform.system.disabled = 1;
+       }
+}
+// -->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: System logs</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<form action="diag_logs_settings.php" method="post" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="diag_logs.php" class="tblnk">System</a></td>
+    <td nowrap class="tabinact"><a href="diag_logs_filter.php" class="tblnk">Firewall</a></td>
+    <td nowrap class="tabinact"><a href="diag_logs_dhcp.php" class="tblnk">DHCP</a></td>
+    <td nowrap class="tabact">Settings</td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+         <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                      <tr> 
+                        <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                        <td width="78%" class="vtable"> <input name="reverse" type="checkbox" id="reverse" value="yes" <?php if ($pconfig['reverse']) echo "checked"; ?>>
+                          <strong>Show log entries in reverse order (newest entries 
+                          on top)</strong></td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                        <td width="78%" class="vtable">Number of log entries to 
+                          show: 
+                          <input name="nentries" id="nentries" type="text" class="formfld" size="4" value="<?=htmlspecialchars($pconfig['nentries']);?>"></td>
+                      </tr>
+                      <tr> 
+                        <td valign="top" class="vtable">&nbsp;</td>
+                        <td class="vtable"> <input name="logdefaultblock" type="checkbox" id="logdefaultblock" value="yes" <?php if ($pconfig['logdefaultblock']) echo "checked"; ?>>
+                          <strong>Log packets blocked by the default rule</strong><br>
+                          Hint: packets that are blocked by the 
+                          implicit default block rule will not be logged anymore 
+                          if you uncheck this option. Per-rule logging options are not affected.</td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                        <td width="78%" class="vtable"> <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+                          <strong>Enable syslog'ing to remote syslog server</strong></td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncell">Remote syslog 
+                          server</td>
+                        <td width="78%" class="vtable"> <input name="remoteserver" id="remoteserver" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['remoteserver']);?>"> 
+                          <br>
+                          IP address of remote syslog server<br> <br> <input name="system" id="system" type="checkbox" value="yes" onclick="enable_change(false)" <?php if ($pconfig['system']) echo "checked"; ?>>
+                          system events <br> <input name="filter" id="filter" type="checkbox" value="yes" <?php if ($pconfig['filter']) echo "checked"; ?>>
+                          firewall events<br> <input name="dhcp" id="dhcp" type="checkbox" value="yes" <?php if ($pconfig['dhcp']) echo "checked"; ?>>
+                          DHCP service events</td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top">&nbsp;</td>
+                        <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                        </td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" height="53" valign="top">&nbsp;</td>
+                        <td width="78%"><strong><span class="red">Note:</span></strong><br>
+                          syslog sends UDP datagrams to port 514 on the specified 
+                          remote syslog server. Be sure to set syslogd on the 
+                          remote server to accept syslog messages from m0n0wall. 
+                        </td>
+                      </tr>
+                    </table>
+    </td>
+  </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_ping.php b/webgui/diag_ping.php
new file mode 100644 (file)
index 0000000..ad12e59
--- /dev/null
@@ -0,0 +1,113 @@
+#!/usr/local/bin/php
+<?php
+/*
+       diag_ping.php
+       part of m0n0wall (http://m0n0.ch/wall)
+
+       Copyright (C) 2003-2004 Bob Zoller (bob@kludgebox.com) and Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+
+       1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+
+       2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+define('MAX_COUNT', 10);
+define('DEFAULT_COUNT', 3);
+
+if ($_POST) {
+       unset($input_errors);
+       unset($do_ping);
+
+       /* input validation */
+       $reqdfields = explode(" ", "host count");
+       $reqdfieldsn = explode(",", "Host,Count");
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+       if (($_POST['count'] < 1) || ($_POST['count'] > MAX_COUNT)) {
+               $input_errors[] = "Count must be between 1 and {MAX_COUNT}";
+       }
+
+       if (!$input_errors) {
+               $do_ping = true;
+               $host = preg_replace ("/[^A-Za-z0-9.]/","",$_POST['host']);
+               $count = $_POST['count'];
+
+       }
+}
+if (!isset($do_ping)) {
+       $do_ping = false;
+       $host = '';
+       $count = DEFAULT_COUNT;
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: Ping</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Diagnostics: Ping</font></p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+                       <form action="diag_ping.php" method="post" name="iform" id="iform">
+                         <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr>
+                                 <td width="22%" valign="top" class="vncellreq">Host</td>
+                                 <td width="78%" class="vtable"> 
+                    <input name="host" type="text" class="formfld" id="host" size="20" value="<?=htmlspecialchars($host);?>"></td>
+                               </tr>
+                               <tr>
+                                 <td width="22%" valign="top" class="vncellreq">Count</td>
+                                 <td width="78%" class="vtable">
+<select name="count" class="formfld" id="count">
+                                       <?php for ($i = 1; $i <= MAX_COUNT; $i++): ?>
+                                       <option value="<?=$i;?>" <?php if ($i == $count) echo "selected"; ?>><?=$i;?></option>
+                                       <?php endfor; ?>
+                                       </select></td>
+                               </tr>
+                               <tr>
+                                 <td width="22%" valign="top">&nbsp;</td>
+                                 <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Ping">
+                               </td>
+                               </tr>
+                               <tr>
+                               <td valign="top" colspan="2">
+                               <? if ($do_ping) {
+                                       echo("<strong>Ping output:</strong><br>");
+                                       echo('<pre>');
+                                       ob_end_flush();
+                                       system("/sbin/ping -c$count " . escapeshellarg($host));
+                                       echo('</pre>');
+                               }
+                               ?>
+                               </td>
+                               </tr>
+                       </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/diag_resetstate.php b/webgui/diag_resetstate.php
new file mode 100644 (file)
index 0000000..058ed5a
--- /dev/null
@@ -0,0 +1,97 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       diag_resetstate.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if ($_POST) {
+
+       $savemsg = "";
+       if ($_POST['nattable']) {
+               filter_flush_nat_table();
+               $savemsg = "The NAT table has been flushed successfully.";
+       }
+       if ($_POST['statetable']) {
+               filter_flush_state_table();
+               if ($savemsg)
+                       $savemsg .= " ";
+               $savemsg .= "The state table has been flushed successfully.";
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Diagnostics: Reset state</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+      <p class="pgtitle">Diagnostics: Reset state</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+            <form action="diag_resetstate.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable"> <p> 
+                      <input name="nattable" type="checkbox" id="nattable" value="yes" checked>
+                      <strong>NAT table</strong><br>
+                      <input name="statetable" type="checkbox" id="statetable" value="yes" checked>
+                      <strong>Firewall state table</strong><br>
+                      <span class="vexpl"><br>
+                      Resetting the state tables will remove all entries from 
+                      the corresponding tables. This means that all open connections 
+                      will be broken and will have to be re-established. This 
+                      may be necessary after making substantial changes to the 
+                      firewall and/or NAT rules, especially if there are IP protocol 
+                      mappings (e.g. for PPTP or IPv6) with open connections.<br>
+                      <br>
+                      </span><span class="vexpl">The firewall will normally leave 
+                      the state tables intact when changing rules.<br>
+                      <br>
+                      NOTE: If you reset the firewall state table, the browser 
+                      session may appear to be hung after clicking &quot;Reset&quot;. 
+                      Simply refresh the page to continue.</span></p>
+                    </td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Reset"> 
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/down.gif b/webgui/down.gif
new file mode 100644 (file)
index 0000000..236339f
Binary files /dev/null and b/webgui/down.gif differ
diff --git a/webgui/down_d.gif b/webgui/down_d.gif
new file mode 100644 (file)
index 0000000..7d84373
Binary files /dev/null and b/webgui/down_d.gif differ
diff --git a/webgui/e.gif b/webgui/e.gif
new file mode 100644 (file)
index 0000000..046a809
Binary files /dev/null and b/webgui/e.gif differ
diff --git a/webgui/err.gif b/webgui/err.gif
new file mode 100644 (file)
index 0000000..a44c78a
Binary files /dev/null and b/webgui/err.gif differ
diff --git a/webgui/exclam.gif b/webgui/exclam.gif
new file mode 100644 (file)
index 0000000..9a6d424
Binary files /dev/null and b/webgui/exclam.gif differ
diff --git a/webgui/exec.php b/webgui/exec.php
new file mode 100644 (file)
index 0000000..80b5d3d
--- /dev/null
@@ -0,0 +1,239 @@
+#!/usr/local/bin/php
+<?php
+if (($_POST['submit'] == "Download") && file_exists($_POST['dlPath'])) {
+       session_cache_limiter('public');
+       $fd = fopen($_POST['dlPath'], "rb");
+       header("Content-Type: application/octet-stream");
+       header("Content-Length: " . filesize($_POST['dlPath']));
+       header("Content-Disposition: attachment; filename=\"" . 
+               trim(htmlentities(basename($_POST['dlPath']))) . "\"");
+       
+       fpassthru($fd);
+       exit;
+} else if (($_POST['submit'] == "Upload") && is_uploaded_file($_FILES['ulfile']['tmp_name'])) {
+       move_uploaded_file($_FILES['ulfile']['tmp_name'], "/tmp/" . $_FILES['ulfile']['name']);
+       $ulmsg = "Uploaded file " . htmlentities($_FILES['ulfile']['name']) . " to /tmp.";
+       unset($_POST['txtCommand']);
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<?php
+
+/*
+       Exec+ v1.02-000 - Copyright 2001-2003, All rights reserved
+       Created by technologEase (http://www.technologEase.com).
+       
+       (modified for m0n0wall by Manuel Kasper <mk@neon1.net>)
+*/
+
+// Function: is Blank
+// Returns true or false depending on blankness of argument.
+
+function isBlank( $arg ) { return ereg( "^\s*$", $arg ); }
+
+
+// Function: Puts
+// Put string, Ruby-style.
+
+function puts( $arg ) { echo "$arg\n"; }
+
+
+// "Constants".
+
+$Version    = '';
+$ScriptName = $HTTP_SERVER_VARS['SCRIPT_NAME'];
+$Title      = 'm0n0wall: execute command';
+
+// Get year.
+
+$arrDT   = localtime();
+$intYear = $arrDT[5] + 1900;
+
+?>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title><?=$Title ?></title>
+<script language="javascript">
+<!--
+
+   // Create recall buffer array (of encoded strings).
+
+<?php
+
+if (isBlank( $_POST['txtRecallBuffer'] )) {
+   puts( "   var arrRecallBuffer = new Array;" );
+} else {
+   puts( "   var arrRecallBuffer = new Array(" );
+   $arrBuffer = explode( "&", $_POST['txtRecallBuffer'] );
+   for ($i=0; $i < (count( $arrBuffer ) - 1); $i++) puts( "      '" . $arrBuffer[$i] . "'," );
+   puts( "      '" . $arrBuffer[count( $arrBuffer ) - 1] . "'" );
+   puts( "   );" );
+}
+
+?>
+
+   // Set pointer to end of recall buffer.
+   var intRecallPtr = arrRecallBuffer.length-1;
+
+   // Functions to extend String class.
+   function str_encode() { return escape( this ) }
+   function str_decode() { return unescape( this ) }
+      
+   // Extend string class to include encode() and decode() functions.
+   String.prototype.encode = str_encode
+   String.prototype.decode = str_decode
+
+   // Function: is Blank
+   // Returns boolean true or false if argument is blank.
+   function isBlank( strArg ) { return strArg.match( /^\s*$/ ) }
+
+   // Function: frmExecPlus onSubmit (event handler)
+   // Builds the recall buffer from the command string on submit.
+   function frmExecPlus_onSubmit( form ) {
+
+      if (!isBlank(form.txtCommand.value)) {
+                 // If this command is repeat of last command, then do not store command.
+                 if (form.txtCommand.value.encode() == arrRecallBuffer[arrRecallBuffer.length-1]) { return true }
+       
+                 // Stuff encoded command string into the recall buffer.
+                 if (isBlank(form.txtRecallBuffer.value))
+                        form.txtRecallBuffer.value = form.txtCommand.value.encode();
+                 else
+                        form.txtRecallBuffer.value += '&' + form.txtCommand.value.encode();
+         }
+
+      return true;
+   }
+
+   // Function: btnRecall onClick (event handler)
+   // Recalls command buffer going either up or down.
+   function btnRecall_onClick( form, n ) {
+
+      // If nothing in recall buffer, then error.
+      if (!arrRecallBuffer.length) {
+         alert( 'Nothing to recall!' );
+         form.txtCommand.focus();
+         return;
+      }
+
+      // Increment recall buffer pointer in positive or negative direction
+      // according to <n>.
+      intRecallPtr += n;
+
+      // Make sure the buffer stays circular.
+      if (intRecallPtr < 0) { intRecallPtr = arrRecallBuffer.length - 1 }
+      if (intRecallPtr > (arrRecallBuffer.length - 1)) { intRecallPtr = 0 }
+
+      // Recall the command.
+      form.txtCommand.value = arrRecallBuffer[intRecallPtr].decode();
+   }
+
+   // Function: Reset onClick (event handler)
+   // Resets form on reset button click event.
+   function Reset_onClick( form ) {
+
+      // Reset recall buffer pointer.
+      intRecallPtr = arrRecallBuffer.length;
+
+      // Clear form (could have spaces in it) and return focus ready for cmd.
+      form.txtCommand.value = '';
+      form.txtCommand.focus();
+
+      return true;
+   }
+//-->
+</script>
+<link href="gui.css" rel="stylesheet" type="text/css">
+<style>
+<!--
+
+input {
+   font-family: courier new, courier;
+   font-weight: normal;
+   font-size: 9pt;
+}
+
+pre {
+   border: 2px solid #435370;
+   background: #F0F0F0;
+   padding: 1em;
+   font-family: courier new, courier;
+   white-space: pre;
+   line-height: 10pt;
+   font-size: 10pt;
+}
+
+.label {
+   font-family: tahoma, verdana, arial, helvetica;
+   font-size: 11px;
+   font-weight: bold;
+}
+
+.button {
+   font-family: tahoma, verdana, arial, helvetica;
+   font-weight: bold;
+   font-size: 11px;
+}
+
+-->
+</style>
+</head>
+<body>
+<p><span class="pgtitle"><?=$Title ?></span>
+<?php if (isBlank($_POST['txtCommand'])): ?>
+<p class="red"><strong>Note: this function is unsupported. Use it
+on your own risk!</strong></p>
+<?php endif; ?>
+<?php if ($ulmsg) echo "<p><strong>" . $ulmsg . "</strong></p>\n"; ?>
+<?php
+
+if (!isBlank($_POST['txtCommand'])) {
+   puts( "<pre>" );
+   puts( "\$ " . htmlspecialchars($_POST['txtCommand']) );
+   putenv("PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
+   $ph = popen( $_POST['txtCommand'], "r" );
+   while ($line = fgets( $ph )) echo htmlspecialchars( $line );
+   pclose( $ph );
+   puts( "</pre>" );
+}
+
+?>
+
+<form action="<?=$ScriptName ?>" method="POST" enctype="multipart/form-data" name="frmExecPlus" onSubmit="return frmExecPlus_onSubmit( this );">
+  <table>
+    <tr>
+      <td class="label" align="right">Command:</td>
+      <td class="type"><input name="txtCommand" type="text" size="80" value="<?=htmlspecialchars($_POST['txtCommand']);?>"></td>
+    </tr>
+    <tr>
+      <td valign="top">&nbsp;&nbsp;&nbsp;</td>
+      <td valign="top" class="label">
+         <input type="hidden" name="txtRecallBuffer" value="<?=$_POST['txtRecallBuffer'] ?>">
+         <input type="button" class="button" name="btnRecallPrev" value="<" onClick="btnRecall_onClick( this.form, -1 );">
+         <input type="submit" class="button" value="Execute">
+         <input type="button" class="button" name="btnRecallNext" value=">" onClick="btnRecall_onClick( this.form,  1 );">
+         <input type="button"  class="button" value="Clear" onClick="return Reset_onClick( this.form );">
+      </td>
+    </tr>
+    <tr>
+      <td height="8"></td>
+      <td></td>
+    </tr>
+    <tr>
+      <td align="right">Download:</td>
+      <td>
+        <input name="dlPath" type="text" id="dlPath" size="50">
+        <input name="submit" type="submit"  class="button" id="download" value="Download">
+        </td>
+    </tr>
+    <tr>
+      <td align="right">Upload:</td>
+      <td valign="top" class="label">
+<input name="ulfile" type="file" class="button" id="ulfile">
+        <input name="submit" type="submit"  class="button" id="upload" value="Upload"></td>
+    </tr>
+  </table>
+</form>
+</body>
+</html>
diff --git a/webgui/exec_raw.php b/webgui/exec_raw.php
new file mode 100644 (file)
index 0000000..6d1ca34
--- /dev/null
@@ -0,0 +1,38 @@
+#!/usr/local/bin/php
+<?php
+/*
+       exec_raw.php
+       part of m0n0wall (http://m0n0.ch/wall)
+
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+
+       1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+
+       2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+header("Content-Type: text/plain");
+
+putenv("PATH=/bin:/sbin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/sbin");
+passthru($_GET['cmd']);
+
+exit(0);
+?>
\ No newline at end of file
diff --git a/webgui/fbegin.inc b/webgui/fbegin.inc
new file mode 100644 (file)
index 0000000..c908229
--- /dev/null
@@ -0,0 +1,103 @@
+<script language="javascript">
+<!--
+var tri_open = "";
+var tri_closed = "";
+
+window.onload = preload;
+
+function preload() {
+       if (document.images) {
+               tri_open = new Image(14,10);
+               tri_closed = new Image(14,10);
+               tri_open.src = "tri_o.gif";
+               tri_closed.src = "tri_c.gif";
+       }
+}
+
+function showhide(tspan, tri) {
+       tspanel = document.getElementById(tspan);
+       triel = document.getElementById(tri);
+       if (tspanel.style.display == 'none') {
+               tspanel.style.display = '';
+               triel.src = "tri_o.gif";
+       } else {
+               tspanel.style.display = 'none';
+               triel.src = "tri_c.gif";
+       }
+}
+-->
+</script>
+<table width="750" border="0" cellspacing="0" cellpadding="2">
+  <tr valign="bottom"> 
+    <td width="150" height="65" align="center" valign="middle"> <strong><a href="http://m0n0.ch/wall" target="_blank"><img src="logo.gif" width="150" height="47" border="0"></a></strong></td>
+    <td height="65" bgcolor="#435370"><span class="tfrtitle">&nbsp;webGUI 
+      Configuration</span></td>
+  </tr>
+  <tr valign="top"> 
+    <td width="150" bgcolor="#9D9D9D">
+       <table width="100%" border="0" cellpadding="6" cellspacing="0">
+        <tr>
+          <td><span class="navlnk"><font color="#FFFFFF"> <strong>System</strong> 
+              <br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="system.php" class="navlnk">General 
+              setup</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="system_routes.php" class="navlnk">Static 
+              routes</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="system_firmware.php" class="navlnk">Firmware</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="system_advanced.php" class="navlnk">Advanced</a><br>
+              <strong>Interfaces</strong>
+                         <?php if (!isset($config['system']['webgui']['noassigninterfaces'])): ?>
+                         <a href="interfaces_assign.php" class="navlnks">(assign)</a>
+                         <?php endif; ?>
+                         <br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="interfaces_lan.php" class="navlnk">LAN</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="interfaces_wan.php" class="navlnk">WAN</a><br>
+                         <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="interfaces_opt.php?index=<?=$i;?>" class="navlnk"><?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?></a><br>
+                         <?php endfor; ?>
+              <strong>Firewall</strong><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="firewall_rules.php" class="navlnk">Rules</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="firewall_nat.php" class="navlnk">NAT</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="firewall_shaper.php" class="navlnk">Traffic 
+              shaper</a> <br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="firewall_aliases.php" class="navlnk">Aliases</a><br>
+              <strong>Services</strong><br>
+                         &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="services_dnsmasq.php" class="navlnk">DNS forwarder</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="services_dyndns.php" class="navlnk">Dynamic 
+              DNS</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="services_dhcp.php" class="navlnk">DHCP</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="services_snmp.php" class="navlnk">SNMP</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="services_proxyarp.php" class="navlnk">Proxy ARP</a><br>
+              <strong>VPN</strong><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="vpn_ipsec.php" class="navlnk">IPsec</a><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="vpn_pptp.php" class="navlnk">PPTP</a><br>
+            &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="vpn_pptp_users.php" class="navlnk">Users</a><br>
+              <strong>Status</strong><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="index.php" class="navlnk">System</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="status_interfaces.php" class="navlnk">Interfaces</a><br>
+              &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="status_wireless.php" class="navlnk">Wireless</a><br>
+                         <?php if (strstr($_SERVER['SCRIPT_FILENAME'], "diag_") || strstr($_SERVER['SCRIPT_FILENAME'], "reboot")): ?>
+                         <a href="javascript:showhide('diag','tri_diag')"><img src="tri_o.gif" id="tri_diag" width="14" height="10" border="0"></a><strong><a href="javascript:showhide('diag','tri_diag')" class="navlnk">Diagnostics</a></strong><br>
+                         <span id="diag">
+                         <?php else: ?>
+                         <a href="javascript:showhide('diag','tri_diag')"><img src="tri_c.gif" id="tri_diag" width="14" height="10" border="0"></a><strong><a href="javascript:showhide('diag','tri_diag')" class="navlnk">Diagnostics</a></strong><br>
+                         <span id="diag" style="display: none">
+                         <?php endif; ?>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="diag_logs.php" class="navlnk">System 
+                                 logs</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="diag_dhcp_leases.php" class="navlnk">DHCP leases</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="diag_ipsec_sad.php" class="navlnk">IPsec</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="diag_ping.php" class="navlnk">Ping</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="diag_resetstate.php" class="navlnk">Reset 
+                                 state</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="diag_backup.php" class="navlnk">Backup/Restore</a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="diag_defaults.php" class="navlnk">Factory 
+                                 defaults </a><br>
+                                 &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="reboot.php" class="navlnk">Reboot 
+                                 system</a>
+                         </span>
+                         </font></span>
+            </td>
+        </tr></table></td>
+    <td width="600"><table width="100%" border="0" cellpadding="10" cellspacing="0">
+        <tr><td>
\ No newline at end of file
diff --git a/webgui/fend.inc b/webgui/fend.inc
new file mode 100644 (file)
index 0000000..f1f5d89
--- /dev/null
@@ -0,0 +1,7 @@
+</td></tr></table></td>
+  </tr>
+  <tr align="center" valign="top" bgcolor="#435370"> 
+    <td colspan="2" class="cpline">m0n0wall is &copy; 2002-2004 by Manuel Kasper. 
+      All rights reserved.&nbsp; [<a href="license.php" class="tblnk">view license</a>]</td>
+  </tr>
+</table>
\ No newline at end of file
diff --git a/webgui/firewall_aliases.php b/webgui/firewall_aliases.php
new file mode 100644 (file)
index 0000000..639292a
--- /dev/null
@@ -0,0 +1,127 @@
+#!/usr/local/bin/php
+<?php
+/*
+       firewall_aliases.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['aliases']['alias']))
+       $config['aliases']['alias'] = array();
+
+aliases_sort();
+$a_aliases = &$config['aliases']['alias'];
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       /* reload all components that use aliases */
+                       $retval = filter_configure();
+                       $retval |= shaper_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               if ($retval == 0) {
+                       if (file_exists($d_aliasesdirty_path))
+                               unlink($d_aliasesdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_aliases[$_GET['id']]) {
+               unset($a_aliases[$_GET['id']]);
+               write_config();
+               touch($d_aliasesdirty_path);
+               header("Location: firewall_aliases.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Aliases</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Aliases</p>
+<form action="firewall_aliases.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_aliasesdirty_path)): ?><p>
+<?php print_info_box_np("The alias list has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td width="25%" class="listhdrr">Name</td>
+                  <td width="30%" class="listhdrr">Address</td>
+                  <td width="35%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_aliases as $alias): ?>
+                <tr>
+                  <td class="listlr">
+                    <?=htmlspecialchars($alias['name']);?>
+                  </td>
+                  <td class="listr">
+                    <?=htmlspecialchars($alias['address']);?>
+                  </td>
+                  <td class="listbg">
+                    <?=htmlspecialchars($alias['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" nowrap class="list"> <a href="firewall_aliases_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="firewall_aliases.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this alias? All elements that still use it will become invalid (e.g. filter rules)!')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="3"></td>
+                  <td class="list"> <a href="firewall_aliases_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+            </form>
+<p><span class="vexpl"><span class="red"><strong>Note:<br>
+                </strong></span>Aliases act as placeholders for real IP addresses 
+                and can be used to minimize the number of changes that have to 
+                be made if a host or network address changes. You can enter the 
+                name of an alias instead of an IP address in all address fields 
+                that have a blue background. The alias will be resolved to its 
+                current address according to the list below. If an alias cannot 
+                be resolved (e.g. because you deleted it), the corresponding element 
+                (e.g. filter/NAT/shaper rule) will be considered invalid and skipped.</span></p>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_aliases_edit.php b/webgui/firewall_aliases_edit.php
new file mode 100644 (file)
index 0000000..d608be8
--- /dev/null
@@ -0,0 +1,196 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_aliases_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['aliases']['alias']))
+       $config['aliases']['alias'] = array();
+
+aliases_sort();
+$a_aliases = &$config['aliases']['alias'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_aliases[$id]) {
+       $pconfig['name'] = $a_aliases[$id]['name'];
+       list($pconfig['address'],$pconfig['address_subnet']) = 
+               explode('/', $a_aliases[$id]['address']);
+       if ($pconfig['address_subnet'])
+               $pconfig['type'] = "network";
+       else
+               $pconfig['type'] = "host";
+       $pconfig['descr'] = $a_aliases[$id]['descr'];
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "name address");
+       $reqdfieldsn = explode(",", "Name,Address");
+       
+       if ($_POST['type'] == "network") {
+               $reqdfields[] = "address_subnet";
+               $reqdfieldsn[] = "Subnet bit count";
+       }
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['name'] && !is_validaliasname($_POST['name']))) {
+               $input_errors[] = "The alias name may only consist of the characters a-z, A-Z, 0-9.";
+       }
+       if (($_POST['address'] && !is_ipaddr($_POST['address']))) {
+               $input_errors[] = "A valid address must be specified.";
+       }
+       if (($_POST['address_subnet'] && !is_numeric($_POST['address_subnet']))) {
+               $input_errors[] = "A valid subnet bit count must be specified.";
+       }
+       
+       /* check for name conflicts */
+       foreach ($a_aliases as $alias) {
+               if (isset($id) && ($a_aliases[$id]) && ($a_aliases[$id] === $alias))
+                       continue;
+
+               if ($alias['name'] == $_POST['name']) {
+                       $input_errors[] = "An alias with this name already exists.";
+                       break;
+               }
+       }
+
+       if (!$input_errors) {
+               $alias = array();
+               $alias['name'] = $_POST['name'];
+               if ($_POST['type'] == "network")
+                       $alias['address'] = $_POST['address'] . "/" . $_POST['address_subnet'];
+               else
+                       $alias['address'] = $_POST['address'];
+               $alias['descr'] = $_POST['descr'];
+
+               if (isset($id) && $a_aliases[$id])
+                       $a_aliases[$id] = $alias;
+               else
+                       $a_aliases[] = $alias;
+               
+               touch($d_aliasesdirty_path);
+               
+               write_config();
+               
+               header("Location: firewall_aliases.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - System: Firewall: Aliases: Edit alias</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+       switch (document.iform.type.selectedIndex) {
+               case 0: /* host */
+                       document.iform.address_subnet.disabled = 1;
+                       document.iform.address_subnet.value = "";
+                       break;
+               case 1: /* network */
+                       document.iform.address_subnet.disabled = 0;
+                       break;
+       }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Aliases: Edit alias</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="firewall_aliases_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td valign="top" class="vncellreq">Name</td>
+                  <td class="vtable"> <input name="name" type="text" class="formfld" id="name" size="40" value="<?=htmlspecialchars($pconfig['name']);?>"> 
+                    <br> <span class="vexpl">The name of the alias may only consist 
+                    of the characters a-z, A-Z and 0-9.</span></td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Type</td>
+                  <td class="vtable"> 
+                    <select name="type" class="formfld" id="type" onChange="typesel_change()">
+                      <option value="host" <?php if ($pconfig['type'] == "host") echo "selected"; ?>>Host</option>
+                      <option value="network" <?php if ($pconfig['type'] == "network") echo "selected"; ?>>Network</option>
+                    </select>
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Address</td>
+                  <td width="78%" class="vtable"> <input name="address" type="text" class="formfld" id="address" size="20" value="<?=htmlspecialchars($pconfig['address']);?>">
+                    / 
+                    <select name="address_subnet" class="formfld" id="address_subnet">
+                      <?php for ($i = 32; $i >= 1; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['address_subnet']) echo "selected"; ?>> 
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select> <br> <span class="vexpl">The address that this alias 
+                    represents.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_aliases[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat.php b/webgui/firewall_nat.php
new file mode 100644 (file)
index 0000000..7df148d
--- /dev/null
@@ -0,0 +1,161 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_nat.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['rule'])) {
+       $config['nat']['rule'] = array();
+}
+nat_rules_sort();
+$a_nat = &$config['nat']['rule'];
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval |= filter_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               
+               if ($retval == 0) {
+                       if (file_exists($d_natconfdirty_path))
+                               unlink($d_natconfdirty_path);
+                       if (file_exists($d_filterconfdirty_path))
+                               unlink($d_filterconfdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_nat[$_GET['id']]) {
+               unset($a_nat[$_GET['id']]);
+               write_config();
+               touch($d_natconfdirty_path);
+               header("Location: firewall_nat.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</font></p>
+<form action="firewall_nat.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabact">Inbound</td>
+    <td nowrap class="tabinact"><a href="firewall_nat_server.php" class="tblnk">Server NAT</a></td>
+    <td nowrap class="tabinact"><a href="firewall_nat_1to1.php" class="tblnk">1:1</a></td>
+    <td nowrap class="tabinact"><a href="firewall_nat_out.php" class="tblnk">Outbound</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr> 
+                  <td width="5%" class="listhdrr">Proto</td>
+                  <td width="20%" class="listhdrr">Ext. port range</td>
+                  <td width="20%" class="listhdrr">NAT IP<br>(ext. IP)</td>
+                  <td width="20%" class="listhdrr">Int. port range</td>
+                  <td width="25%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_nat as $natent): ?>
+                <tr valign="top"> 
+                  <td class="listlr"> 
+                    <?=strtoupper($natent['protocol']);?>
+                  </td>
+                  <td class="listr">
+                    <?php 
+                                               list($beginport, $endport) = split("-", $natent['external-port']);
+                                               if ((!$endport) || ($beginport == $endport)) {
+                                                       echo $beginport;
+                                                       if ($wkports[$beginport])
+                                                               echo " (" . $wkports[$beginport] . ")";
+                                               } else
+                                                       echo $beginport . " - " . $endport;
+                                 ?>
+                  </td>
+                  <td class="listr"> 
+                    <?=$natent['target'];?>
+                                       <?php if ($natent['external-address'])
+                                               echo "<br>(" . $natent['external-address'] . ")";
+                                       ?>
+                  </td>
+                  <td class="listr"> 
+                    <?php if ((!$endport) || ($beginport == $endport)) {
+                                                       echo $natent['local-port'];
+                                                       if ($wkports[$natent['local-port']])
+                                                               echo " (" . $wkports[$natent['local-port']] . ")";
+                                               } else
+                                                       echo $natent['local-port'] . " - " . 
+                                                               ($natent['local-port']+$endport-$beginport);
+                                 ?>
+                  </td>
+                  <td class="listbg"> 
+                    <?=htmlspecialchars($natent['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" class="list" nowrap> <a href="firewall_nat_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="firewall_nat.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this rule?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="5"></td>
+                  <td class="list"> <a href="firewall_nat_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+                    <p><span class="vexpl"><span class="red"><strong>Note:<br>
+                      </strong></span>It is not possible to access NATed services 
+                      using the WAN IP address from within LAN (or an optional 
+                      network).</span></p></td>
+  </tr>
+</table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat_1to1.php b/webgui/firewall_nat_1to1.php
new file mode 100644 (file)
index 0000000..d3ab765
--- /dev/null
@@ -0,0 +1,136 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_nat_1to1.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['onetoone'])) {
+       $config['nat']['onetoone'] = array();
+}
+$a_1to1 = &$config['nat']['onetoone'];
+nat_1to1_rules_sort();
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval |= filter_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               
+               if ($retval == 0) {
+                       if (file_exists($d_natconfdirty_path))
+                               unlink($d_natconfdirty_path);
+                       if (file_exists($d_filterconfdirty_path))
+                               unlink($d_filterconfdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_1to1[$_GET['id']]) {
+               unset($a_1to1[$_GET['id']]);
+               write_config();
+               touch($d_natconfdirty_path);
+               header("Location: firewall_nat_1to1.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</p>
+<form action="firewall_nat_1to1.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="firewall_nat.php" class="tblnk">Inbound</a></td>
+    <td nowrap class="tabinact"><a href="firewall_nat_server.php" class="tblnk">Server NAT</a></td>
+    <td nowrap class="tabact">1:1</td>
+    <td nowrap class="tabinact"><a href="firewall_nat_out.php" class="tblnk">Outbound</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr> 
+                  <td width="20%" class="listhdrr">External IP</td>
+                  <td width="20%" class="listhdrr">Internal IP</td>
+                  <td width="50%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_1to1 as $natent): ?>
+                <tr> 
+                  <td class="listlr"> 
+                    <?php echo $natent['external'];
+                                       if ($natent['subnet']) echo "/" . $natent['subnet']; ?>
+                  </td>
+                  <td class="listr"> 
+                    <?php echo $natent['internal'];
+                                       if ($natent['subnet']) echo "/" . $natent['subnet']; ?>
+                  </td>
+                  <td class="listbg"> 
+                    <?=htmlspecialchars($natent['descr']);?>&nbsp;
+                  </td>
+                  <td class="list" nowrap> <a href="firewall_nat_1to1_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="firewall_nat_1to1.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this mapping?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="3"></td>
+                  <td class="list"> <a href="firewall_nat_1to1_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+                                                       <p><span class="vexpl"><span class="red"><strong>Note:<br>
+                      </strong></span>Depending on the way your WAN connection is setup, you may also need <a href="services_proxyarp.php">proxy ARP</a>.</span></p>
+</td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat_1to1_edit.php b/webgui/firewall_nat_1to1_edit.php
new file mode 100644 (file)
index 0000000..135650a
--- /dev/null
@@ -0,0 +1,194 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_nat_1to1_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['onetoone'])) {
+       $config['nat']['onetoone'] = array();
+}
+nat_1to1_rules_sort();
+$a_1to1 = &$config['nat']['onetoone'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_1to1[$id]) {
+       $pconfig['external'] = $a_1to1[$id]['external'];
+       $pconfig['internal'] = $a_1to1[$id]['internal'];
+       if (!$a_1to1[$id]['subnet'])
+               $pconfig['subnet'] = 32;
+       else
+               $pconfig['subnet'] = $a_1to1[$id]['subnet'];
+       $pconfig['descr'] = $a_1to1[$id]['descr'];
+} else {
+    $pconfig['subnet'] = 32;
+}
+
+if ($_POST) {
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "external internal");
+       $reqdfieldsn = explode(",", "External subnet,Internal subnet");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+       if (($_POST['external'] && !is_ipaddr($_POST['external']))) {
+               $input_errors[] = "A valid external subnet must be specified.";
+       }
+       if (($_POST['internal'] && !is_ipaddr($_POST['internal']))) {
+               $input_errors[] = "A valid internal subnet must be specified.";
+       }
+       
+       if (is_ipaddr($config['interfaces']['wan']['ipaddr'])) {
+               if (check_subnets_overlap($_POST['external'], $_POST['subnet'], 
+                               $config['interfaces']['wan']['ipaddr'], 32))
+                       $input_errors[] = "The WAN IP address may not be used in a 1:1 rule.";
+       }
+       
+       /* check for overlaps with other 1:1 */
+       foreach ($a_1to1 as $natent) {
+               if (isset($id) && ($a_1to1[$id]) && ($a_1to1[$id] === $natent))
+                       continue;
+               
+               if (check_subnets_overlap($_POST['external'], $_POST['subnet'], $natent['external'], $natent['subnet'])) {
+                       $input_errors[] = "Another 1:1 rule overlaps with the specified external subnet.";
+                       break;
+               } else if (check_subnets_overlap($_POST['internal'], $_POST['subnet'], $natent['internal'], $natent['subnet'])) {
+                       $input_errors[] = "Another 1:1 rule overlaps with the specified internal subnet.";
+                       break;
+               }
+       }
+       
+       /* check for overlaps with server NAT */
+       if (is_array($config['nat']['servernat'])) {
+               foreach ($config['nat']['servernat'] as $natent) {
+                       if (check_subnets_overlap($_POST['external'], $_POST['subnet'],
+                               $natent['ipaddr'], 32)) {
+                               $input_errors[] = "A server NAT entry overlaps with the specified external subnet.";
+                               break;
+                       }
+               }
+       }
+       
+       /* check for overlaps with advanced outbound NAT */
+       if (is_array($config['nat']['advancedoutbound']['rule'])) {
+               foreach ($config['nat']['advancedoutbound']['rule'] as $natent) {
+                       if ($natent['target'] && 
+                               check_subnets_overlap($_POST['external'], $_POST['subnet'], $natent['target'], 32)) {
+                               $input_errors[] = "An advanced outbound NAT entry overlaps with the specified external subnet.";
+                               break;
+                       }
+               }
+       }
+
+       if (!$input_errors) {
+               $natent = array();
+               $natent['external'] = $_POST['external'];
+               $natent['internal'] = $_POST['internal'];
+               $natent['subnet'] = $_POST['subnet'];
+               $natent['descr'] = $_POST['descr'];
+               
+               if (isset($id) && $a_1to1[$id])
+                       $a_1to1[$id] = $natent;
+               else
+                       $a_1to1[] = $natent;
+               
+               touch($d_natconfdirty_path);
+               
+               write_config();
+               
+               header("Location: firewall_nat_1to1.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT: Edit 1:1</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit 1:1</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="firewall_nat_1to1_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">External subnet</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="external" type="text" class="formfld" id="external" size="20" value="<?=htmlspecialchars($pconfig['external']);?>">
+                    / 
+                    <select name="subnet" class="formfld" id="subnet">
+                      <?php for ($i = 32; $i >= 0; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>>
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select>
+                    <br>
+                    <span class="vexpl">Enter the external (WAN) subnet for the 1:1 mapping. You may map single IP addresses by specifying a /32 subnet.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Internal subnet</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="internal" type="text" class="formfld" id="internal" size="20" value="<?=htmlspecialchars($pconfig['internal']);?>"> 
+                    <br>
+                     <span class="vexpl">Enter the internal (LAN) subnet for the 1:1 mapping. The subnet size specified for the external subnet also applies to the internal subnet (they  have to be the same).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_1to1[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat_edit.php b/webgui/firewall_nat_edit.php
new file mode 100644 (file)
index 0000000..a3f4719
--- /dev/null
@@ -0,0 +1,334 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_nat_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['rule'])) {
+       $config['nat']['rule'] = array();
+}
+nat_rules_sort();
+$a_nat = &$config['nat']['rule'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_nat[$id]) {
+       $pconfig['extaddr'] = $a_nat[$id]['external-address'];
+       $pconfig['proto'] = $a_nat[$id]['protocol'];
+       list($pconfig['beginport'],$pconfig['endport']) = explode("-", $a_nat[$id]['external-port']);
+       $pconfig['localip'] = $a_nat[$id]['target'];
+       $pconfig['localbeginport'] = $a_nat[$id]['local-port'];
+       $pconfig['descr'] = $a_nat[$id]['descr'];
+}
+
+if ($_POST) {
+
+       if ($_POST['beginport_cust'] && !$_POST['beginport'])
+               $_POST['beginport'] = $_POST['beginport_cust'];
+       if ($_POST['endport_cust'] && !$_POST['endport'])
+               $_POST['endport'] = $_POST['endport_cust'];
+       if ($_POST['localbeginport_cust'] && !$_POST['localbeginport'])
+               $_POST['localbeginport'] = $_POST['localbeginport_cust'];
+               
+       if (!$_POST['endport'])
+               $_POST['endport'] = $_POST['beginport'];
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "proto beginport localip localbeginport");
+       $reqdfieldsn = explode(",", "Protocol,Start port,NAT IP,Local port");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['beginport'] && !is_port($_POST['beginport']))) {
+               $input_errors[] = "The start port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['endport'] && !is_port($_POST['endport']))) {
+               $input_errors[] = "The end port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['localbeginport'] && !is_port($_POST['localbeginport']))) {
+               $input_errors[] = "The local port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['localip'] && !is_ipaddroralias($_POST['localip']))) {
+               $input_errors[] = "A valid NAT IP address or host alias must be specified.";
+       }
+       
+       if ($_POST['beginport'] > $_POST['endport']) {
+               /* swap */
+               $tmp = $_POST['endport'];
+               $_POST['endport'] = $_POST['beginport'];
+               $_POST['beginport'] = $tmp;
+       }
+       
+       /* check for overlaps */
+       foreach ($a_nat as $natent) {
+               if (isset($id) && ($a_nat[$id]) && ($a_nat[$id] === $natent))
+                       continue;
+               if ($natent['external-address'] != $_POST['extaddr'])
+                       continue;
+               
+               list($begp,$endp) = explode("-", $natent['external-port']);
+               if (!$endp)
+                       $endp = $begp;
+               
+               if (!(   (($_POST['beginport'] < $begp) && ($_POST['endport'] < $begp))
+                     || (($_POST['beginport'] > $endp) && ($_POST['endport'] > $endp)))) {
+                       
+                       $input_errors[] = "The external port range overlaps with an existing entry.";
+                       break;
+               }
+       }
+
+       if (!$input_errors) {
+               $natent = array();
+               if ($_POST['extaddr'])
+                       $natent['external-address'] = $_POST['extaddr'];
+               $natent['protocol'] = $_POST['proto'];
+               
+               if ($_POST['beginport'] == $_POST['endport'])
+                       $natent['external-port'] = $_POST['beginport'];
+               else
+                       $natent['external-port'] = $_POST['beginport'] . "-" . $_POST['endport'];
+               
+               $natent['target'] = $_POST['localip'];
+               $natent['local-port'] = $_POST['localbeginport'];
+               $natent['descr'] = $_POST['descr'];
+               
+               if (isset($id) && $a_nat[$id])
+                       $a_nat[$id] = $natent;
+               else
+                       $a_nat[] = $natent;
+               
+               touch($d_natconfdirty_path);
+               
+               if ($_POST['autoadd']) {
+                       /* auto-generate a matching firewall rule */
+                       $filterent = array();           
+                       $filterent['interface'] = "wan";
+                       $filterent['protocol'] = $_POST['proto'];
+                       $filterent['source']['any'] = "";
+                       $filterent['destination']['address'] = $_POST['localip'];
+                       
+                       $dstpfrom = $_POST['localbeginport'];
+                       $dstpto = $dstpfrom + $_POST['endport'] - $_POST['beginport'];
+                       
+                       if ($dstpfrom == $dstpto)
+                               $filterent['destination']['port'] = $dstpfrom;
+                       else
+                               $filterent['destination']['port'] = $dstpfrom . "-" . $dstpto;
+                       
+                       $filterent['descr'] = "NAT " . $_POST['descr'];
+                       
+                       $config['filter']['rule'][] = $filterent;
+                       
+                       touch($d_filterconfdirty_path);
+               }
+               
+               write_config();
+               
+               header("Location: firewall_nat.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT: Edit</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function ext_change() {
+       if (document.iform.beginport.selectedIndex == 0) {
+               document.iform.beginport_cust.disabled = 0;
+       } else {
+               document.iform.beginport_cust.value = "";
+               document.iform.beginport_cust.disabled = 1;
+       }
+       if (document.iform.endport.selectedIndex == 0) {
+               document.iform.endport_cust.disabled = 0;
+       } else {
+               document.iform.endport_cust.value = "";
+               document.iform.endport_cust.disabled = 1;
+       }
+       if (document.iform.localbeginport.selectedIndex == 0) {
+               document.iform.localbeginport_cust.disabled = 0;
+       } else {
+               document.iform.localbeginport_cust.value = "";
+               document.iform.localbeginport_cust.disabled = 1;
+       }
+}
+function ext_rep_change() {
+       document.iform.endport.selectedIndex = document.iform.beginport.selectedIndex;
+       document.iform.localbeginport.selectedIndex = document.iform.beginport.selectedIndex;
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="firewall_nat_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                           <tr> 
+                  <td width="22%" valign="top" class="vncellreq">External address</td>
+                  <td width="78%" class="vtable"> 
+                    <select name="extaddr" class="formfld">
+                                         <option value="" <?php if (!$pconfig['extaddr']) echo "selected"; ?>>WAN</option>
+                      <?php
+                                         if (is_array($config['nat']['servernat'])):
+                                                 foreach ($config['nat']['servernat'] as $sn): ?>
+                      <option value="<?=$sn['ipaddr'];?>" <?php if ($sn['ipaddr'] == $pconfig['extaddr']) echo "selected"; ?>><?=htmlspecialchars("{$sn['ipaddr']} ({$sn['descr']})");?></option>
+                      <?php endforeach; endif; ?>
+                    </select><br><span class="vexpl">
+                                       If you want this rule to apply to another IP address than m0n0wall's WAN IP address,
+                                       select it here (you need to define IP addresses on the
+                                       <a href="firewall_nat_server.php">Server NAT</a> page first).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
+                  <td width="78%" class="vtable"> 
+                    <select name="proto" class="formfld">
+                      <?php $protocols = explode(" ", "TCP UDP TCP/UDP"); foreach ($protocols as $proto): ?>
+                      <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>><?=htmlspecialchars($proto);?></option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Choose which IP protocol 
+                    this rule should match.<br>
+                    Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">External port 
+                    range </td>
+                  <td width="78%" class="vtable"> 
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>from:&nbsp;&nbsp;</td>
+                        <td><select name="beginport" class="formfld" onChange="ext_rep_change();ext_change()">
+                            <option value="">(other)</option>
+                            <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['beginport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>>
+                                                       <?=htmlspecialchars($wkportdesc);?>
+                                                       </option>
+                            <?php endforeach; ?>
+                          </select> <input name="beginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['beginport']; ?>"></td>
+                      </tr>
+                      <tr> 
+                        <td>to:</td>
+                        <td><select name="endport" class="formfld" onChange="ext_change()">
+                            <option value="">(other)</option>
+                            <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['endport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>>
+                                                       <?=htmlspecialchars($wkportdesc);?>
+                                                       </option>
+                                                       <?php endforeach; ?>
+                          </select> <input name="endport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['endport']; ?>"></td>
+                      </tr>
+                    </table>
+                    <br> <span class="vexpl">Specify the port or port range on 
+                    the firewall's external address for this mapping.<br>
+                    Hint: you can leave the <em>'to'</em> field empty if you only 
+                    want to map a single port</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">NAT IP</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="localip" type="text" class="formfldalias" id="localip" size="20" value="<?=htmlspecialchars($pconfig['localip']);?>"> 
+                    <br> <span class="vexpl">Enter the internal IP address of 
+                    the server on which you want to map the ports.<br>
+                    e.g. <em>192.168.1.12</em></span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Local port</td>
+                  <td width="78%" class="vtable"> 
+                    <select name="localbeginport" class="formfld" onChange="ext_change()">
+                      <option value="">(other)</option>
+                      <?php $bfound = 0; foreach ($wkports as $wkport => $wkportdesc): ?>
+                      <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['localbeginport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>>
+                                         <?=htmlspecialchars($wkportdesc);?>
+                                         </option>
+                      <?php endforeach; ?>
+                    </select> <input name="localbeginport_cust" type="text" size="5" value="<?php if (!$bfound) echo $pconfig['localbeginport']; ?>"> 
+                    <br>
+                    <span class="vexpl">Specify the port on the machine with the 
+                    IP address entered above. In case of a port range, specify 
+                    the beginning port of the range (the end port will be calculated 
+                    automatically).<br>
+                    Hint: this is usually identical to the 'from' port above</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr><?php if (!(isset($id) && $a_nat[$id])): ?>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="autoadd" type="checkbox" id="autoadd" value="yes">
+                    <strong>Auto-add a firewall rule to permit traffic through 
+                    this NAT rule</strong></td>
+                </tr><?php endif; ?>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_nat[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+ext_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat_out.php b/webgui/firewall_nat_out.php
new file mode 100644 (file)
index 0000000..6c812ea
--- /dev/null
@@ -0,0 +1,175 @@
+#!/usr/local/bin/php
+<?php 
+/*
+    firewall_nat_out.php
+    part of m0n0wall (http://m0n0.ch/wall)
+    
+    Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+    All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+    
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    
+    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['advancedoutbound']['rule']))
+    $config['nat']['advancedoutbound']['rule'] = array();
+    
+$a_out = &$config['nat']['advancedoutbound']['rule'];
+nat_out_rules_sort();
+
+if ($_POST) {
+
+    $pconfig = $_POST;
+
+    $config['nat']['advancedoutbound']['enable'] = ($_POST['enable']) ? true : false;
+    write_config();
+    
+    $retval = 0;
+    
+    if (!file_exists($d_sysrebootreqd_path)) {
+               config_lock();
+        $retval |= filter_configure();
+               config_unlock();
+    }
+    $savemsg = get_std_save_message($retval);
+    
+    if ($retval == 0) {
+        if (file_exists($d_natconfdirty_path))
+            unlink($d_natconfdirty_path);
+        if (file_exists($d_filterconfdirty_path))
+            unlink($d_filterconfdirty_path);
+    }
+}
+
+if ($_GET['act'] == "del") {
+    if ($a_out[$_GET['id']]) {
+        unset($a_out[$_GET['id']]);
+        write_config();
+        touch($d_natconfdirty_path);
+        header("Location: firewall_nat_out.php");
+        exit;
+    }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</p>
+<form action="firewall_nat_out.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="firewall_nat.php" class="tblnk">Inbound</a></td>
+    <td nowrap class="tabinact"><a href="firewall_nat_server.php" class="tblnk">Server NAT</a></td>
+    <td nowrap class="tabinact"><a href="firewall_nat_1to1.php" class="tblnk">1:1</a></td>
+    <td nowrap class="tabact">Outbound</td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td class="vtable"><p>
+                      <input name="enable" type="checkbox" id="enable" value="yes" <?php if (isset($config['nat']['advancedoutbound']['enable'])) echo "checked";?>>
+                      <strong>Enable advanced outbound NAT<br>
+                      </strong></p></td>
+                </tr>
+                <tr> 
+                  <td> <input name="submit" type="submit" class="formbtn" value="Save"> 
+                  </td>
+                </tr>
+                <tr>
+                  <td><p><span class="vexpl"><span class="red"><strong>Note:<br>
+                      </strong></span>If advanced outbound NAT is enabled, no outbound NAT
+                      rules will be automatically generated anymore. Instead, only the mappings
+                      you specify below will be used. With advanced outbound NAT disabled,
+                      a mapping is automatically created for each interface's subnet
+                      (except WAN).</span> If you use target addresses other than the WAN interface's IP address, then depending on<span class="vexpl"> the way your WAN connection is setup, you may also need <a href="services_proxyarp.php">proxy ARP</a>.</span><br>
+                      <br>
+                      You may enter your own mappings below.</p>
+                    </td>
+                </tr>
+              </table>
+              &nbsp;<br>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr> 
+                  <td width="20%" class="listhdrr">Source</td>
+                  <td width="20%" class="listhdrr">Destination</td>
+                  <td width="20%" class="listhdrr">Target</td>
+                  <td width="30%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                </tr>
+              <?php $i = 0; foreach ($a_out as $natent): ?>
+                <tr> 
+                  <td class="listlr"> 
+                    <?=$natent['source']['network'];?>
+                  </td>
+                  <td class="listr"> 
+                    <?php
+                      if (isset($natent['destination']['any']))
+                          echo "*";
+                      else {
+                          if (isset($natent['destination']['not']))
+                              echo "!&nbsp;";
+                          echo $natent['destination']['network'];
+                      }
+                    ?>
+                  </td>
+                  <td class="listr"> 
+                    <?php
+                      if (!$natent['target'])
+                          echo "*";
+                      else
+                          echo $natent['target'];
+                    ?>
+                  </td>
+                  <td class="listbg"> 
+                    <?=htmlspecialchars($natent['descr']);?>&nbsp;
+                  </td>
+                  <td class="list" nowrap> <a href="firewall_nat_out_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="firewall_nat_out.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this mapping?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                </tr>
+              <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="4"></td>
+                  <td class="list"> <a href="firewall_nat_out_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                </tr>
+              </table>
+</td>
+  </tr>
+</table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat_out_edit.php b/webgui/firewall_nat_out_edit.php
new file mode 100644 (file)
index 0000000..b9625f8
--- /dev/null
@@ -0,0 +1,286 @@
+#!/usr/local/bin/php
+<?php 
+/*
+    firewall_nat_out_edit.php
+    part of m0n0wall (http://m0n0.ch/wall)
+    
+    Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+    All rights reserved.
+    
+    Redistribution and use in source and binary forms, with or without
+    modification, are permitted provided that the following conditions are met:
+    
+    1. Redistributions of source code must retain the above copyright notice,
+       this list of conditions and the following disclaimer.
+    
+    2. Redistributions in binary form must reproduce the above copyright
+       notice, this list of conditions and the following disclaimer in the
+       documentation and/or other materials provided with the distribution.
+    
+    THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+    INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+    AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+    AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+    OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+    SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+    INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+    CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+    ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+    POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['advancedoutbound']['rule']))
+    $config['nat']['advancedoutbound']['rule'] = array();
+    
+$a_out = &$config['nat']['advancedoutbound']['rule'];
+nat_out_rules_sort();
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+    $id = $_POST['id'];
+
+function network_to_pconfig($adr, &$padr, &$pmask, &$pnot) {
+
+    if (isset($adr['any']))
+        $padr = "any";
+    else if ($adr['network']) {
+        list($padr, $pmask) = explode("/", $adr['network']);
+        if (!$pmask)
+            $pmask = 32;
+    }
+
+    if (isset($adr['not']))
+        $pnot = 1;
+    else
+        $pnot = 0;
+}
+
+if (isset($id) && $a_out[$id]) {
+    list($pconfig['source'],$pconfig['source_subnet']) = explode('/', $a_out[$id]['source']['network']);
+    network_to_pconfig($a_out[$id]['destination'], $pconfig['destination'],
+          $pconfig['destination_subnet'], $pconfig['destination_not']);
+    $pconfig['target'] = $a_out[$id]['target'];
+    $pconfig['descr'] = $a_out[$id]['descr'];
+} else {
+    $pconfig['source_subnet'] = 24;
+    $pconfig['destination'] = "any";
+    $pconfig['destination_subnet'] = 24;
+}
+
+if ($_POST) {
+    
+    if ($_POST['destination_type'] == "any") {
+        $_POST['destination'] = "any";
+        $_POST['destination_subnet'] = 24;
+    }
+    
+    unset($input_errors);
+    $pconfig = $_POST;
+
+    /* input validation */
+    $reqdfields = explode(" ", "source source_subnet destination destination_subnet");
+    $reqdfieldsn = explode(",", "Source,Source bit count,Destination,Destination bit count");
+    
+    do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+    if ($_POST['source'] && !is_ipaddr($_POST['source'])) {
+        $input_errors[] = "A valid source must be specified.";
+    }
+    if ($_POST['source_subnet'] && !is_numericint($_POST['source_subnet'])) {
+        $input_errors[] = "A valid source bit count must be specified.";
+    }
+    if ($_POST['destination_type'] != "any") {
+        if ($_POST['destination'] && !is_ipaddr($_POST['destination'])) {
+            $input_errors[] = "A valid destination must be specified.";
+        }
+        if ($_POST['destination_subnet'] && !is_numericint($_POST['destination_subnet'])) {
+            $input_errors[] = "A valid destination bit count must be specified.";
+        }
+    }
+    if ($_POST['target'] && !is_ipaddr($_POST['target'])) {
+        $input_errors[] = "A valid target IP address must be specified.";
+    }
+    
+    /* check for existing entries */
+    $osn = gen_subnet($_POST['source'], $_POST['source_subnet']) . "/" . $_POST['source_subnet'];
+    if ($_POST['destination_type'] == "any")
+        $ext = "any";
+    else
+        $ext = gen_subnet($_POST['destination'], $_POST['destination_subnet']) . "/"
+            . $_POST['destination_subnet'];
+                       
+       if ($_POST['target']) {
+               /* check for clashes with 1:1 NAT (Server NAT is OK) */
+               if (is_array($config['nat']['onetoone'])) {
+                       foreach ($config['nat']['onetoone'] as $natent) {
+                               if (check_subnets_overlap($_POST['target'], 32, $natent['external'], $natent['subnet'])) {
+                                       $input_errors[] = "A 1:1 NAT mapping overlaps with the specified target IP address.";
+                                       break;
+                               }
+                       }
+               }
+       }
+    
+    foreach ($a_out as $natent) {
+        if (isset($id) && ($a_out[$id]) && ($a_out[$id] === $natent))
+            continue;
+        
+        if ($natent['source']['network'] == $osn) {
+            if (isset($natent['destination']['not']) == isset($_POST['destination_not'])) {
+                if ((isset($natent['destination']['any']) && ($ext == "any")) ||
+                        ($natent['destination']['network'] == $ext)) {
+                    $input_errors[] = "There is already an outbound NAT rule with the specified settings.";
+                    break;
+                }
+            }
+        }
+    }
+
+    if (!$input_errors) {
+        $natent = array();
+        $natent['source']['network'] = $osn;
+        $natent['descr'] = $_POST['descr'];
+        $natent['target'] = $_POST['target'];
+        
+        if ($ext == "any")
+            $natent['destination']['any'] = true;
+        else
+            $natent['destination']['network'] = $ext;
+        
+        if (isset($_POST['destination_not']) && $ext != "any")
+            $natent['destination']['not'] = true;
+        
+        if (isset($id) && $a_out[$id])
+            $a_out[$id] = $natent;
+        else
+            $a_out[] = $natent;
+        
+        touch($d_natconfdirty_path);
+        
+        write_config();
+        
+        header("Location: firewall_nat_out.php");
+        exit;
+    }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT: Edit outbound mapping</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+    switch (document.iform.destination_type.selectedIndex) {
+        case 1: // network
+            document.iform.destination.disabled = 0;
+            document.iform.destination_subnet.disabled = 0;
+            break;
+        default:
+            document.iform.destination.value = "";
+            document.iform.destination.disabled = 1;
+            document.iform.destination_subnet.value = "24";
+            document.iform.destination_subnet.disabled = 1;
+            break;
+    }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit outbound mapping</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="firewall_nat_out_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Source</td>
+                  <td width="78%" class="vtable">
+<input name="source" type="text" class="formfld" id="source" size="20" value="<?=htmlspecialchars($pconfig['source']);?>">
+                     
+                  / 
+                    <select name="source_subnet" class="formfld" id="source_subnet">
+                      <?php for ($i = 32; $i >= 0; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['source_subnet']) echo "selected"; ?>>
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select>
+                    <br>
+                     <span class="vexpl">Enter the source network for the outbound NAT mapping.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Destination</td>
+                  <td width="78%" class="vtable">
+<input name="destination_not" type="checkbox" id="destination_not" value="yes" <?php if ($pconfig['destination_not']) echo "checked"; ?>>
+                    <strong>not</strong><br>
+                    Use this option to invert the sense of the match.<br>
+                    <br>
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>Type:&nbsp;&nbsp;</td>
+                        <td><select name="destination_type" class="formfld" onChange="typesel_change()">
+                            <option value="any" <?php if ($pconfig['destination'] == "any") echo "selected"; ?>> 
+                            any</option>
+                            <option value="network" <?php if ($pconfig['destination'] != "any") echo "selected"; ?>> 
+                            Network</option>
+                          </select></td>
+                      </tr>
+                      <tr> 
+                        <td>Address:&nbsp;&nbsp;</td>
+                        <td><input name="destination" type="text" class="formfld" id="destination" size="20" value="<?=htmlspecialchars($pconfig['destination']);?>">
+                          / 
+                          <select name="destination_subnet" class="formfld" id="destination_subnet">
+                            <?php for ($i = 32; $i >= 0; $i--): ?>
+                            <option value="<?=$i;?>" <?php if ($i == $pconfig['destination_subnet']) echo "selected"; ?>> 
+                            <?=$i;?>
+                            </option>
+                            <?php endfor; ?>
+                          </select> </td>
+                      </tr>
+                      <tr>
+                        <td>&nbsp;</td>
+                        <td><span class="vexpl">Enter the destination network for 
+                          the outbound NAT mapping.</span></td>
+                      </tr>
+                    </table></td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">Target</td>
+                  <td class="vtable">
+<input name="target" type="text" class="formfld" id="target" size="20" value="<?=htmlspecialchars($pconfig['target']);?>">
+                    <br>
+                     <span class="vexpl">Packets matching this rule will be mapped to the IP address given here. Leave blank to use the WAN interface's IP address.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_out[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat_server.php b/webgui/firewall_nat_server.php
new file mode 100644 (file)
index 0000000..bebceeb
--- /dev/null
@@ -0,0 +1,143 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_nat_server.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['servernat'])) {
+       $config['nat']['servernat'] = array();
+}
+$a_snat = &$config['nat']['servernat'];
+nat_server_rules_sort();
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval |= filter_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               
+               if ($retval == 0) {
+                       if (file_exists($d_natconfdirty_path))
+                               unlink($d_natconfdirty_path);
+                       if (file_exists($d_filterconfdirty_path))
+                               unlink($d_filterconfdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_snat[$_GET['id']]) {
+               /* make sure no inbound NAT mappings reference this entry */
+               if (is_array($config['nat']['rule'])) {
+                       foreach ($config['nat']['rule'] as $rule) {
+                               if ($rule['external-address'] == $a_snat[$_GET['id']]['ipaddr']) {
+                                       $input_errors[] = "This entry cannot be deleted because it is still referenced by at least one inbound NAT mapping.";
+                                       break;
+                               }
+                       }
+               }
+               
+               if (!$input_errors) {
+                       unset($a_snat[$_GET['id']]);
+                       write_config();
+                       touch($d_natconfdirty_path);
+                       header("Location: firewall_nat_server.php");
+                       exit;
+               }
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT</p>
+<form action="firewall_nat_server.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_natconfdirty_path)): ?><p>
+<?php print_info_box_np("The NAT configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="firewall_nat.php" class="tblnk">Inbound</a></td>
+    <td nowrap class="tabact">Server NAT</td>
+    <td nowrap class="tabinact"><a href="firewall_nat_1to1.php" class="tblnk">1:1</a></td>
+    <td nowrap class="tabinact"><a href="firewall_nat_out.php" class="tblnk">Outbound</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="5" class="tabcont">
+              <table width="80%" border="0" cellpadding="0" cellspacing="0">
+                <tr> 
+                  <td width="40%" class="listhdrr">External IP</td>
+                  <td width="50%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_snat as $natent): ?>
+                <tr> 
+                  <td class="listlr"> 
+                    <?=$natent['ipaddr'];?>
+                  </td>
+                  <td class="listbg"> 
+                    <?=htmlspecialchars($natent['descr']);?>&nbsp;
+                  </td>
+                  <td class="list" nowrap> <a href="firewall_nat_server_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="firewall_nat_server.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this entry?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="2"></td>
+                  <td class="list"> <a href="firewall_nat_server_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+                               <p><span class="vexpl"><span class="red"><strong>Note:<br>
+                      </strong></span>The external IP addresses defined on this page may be used in <a href="firewall_nat.php">inbound NAT</a> mappings. Depending on the way your WAN connection is setup, you may also need <a href="services_proxyarp.php">proxy ARP</a>.</span></p>
+</td>
+  </tr>
+</table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_nat_server_edit.php b/webgui/firewall_nat_server_edit.php
new file mode 100644 (file)
index 0000000..6baafb2
--- /dev/null
@@ -0,0 +1,149 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_nat_server_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['nat']['servernat'])) {
+       $config['nat']['servernat'] = array();
+}
+nat_server_rules_sort();
+$a_snat = &$config['nat']['servernat'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_snat[$id]) {
+       $pconfig['ipaddr'] = $a_snat[$id]['ipaddr'];
+       $pconfig['descr'] = $a_snat[$id]['descr'];
+}
+
+if ($_POST) {
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "ipaddr");
+       $reqdfieldsn = explode(",", "External IP address");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+       if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+               $input_errors[] = "A valid external IP address must be specified.";
+       }
+       
+       if ($_POST['ipaddr'] == $config['interfaces']['wan']['ipaddr'])
+               $input_errors[] = "The WAN IP address may not be used in a Server NAT entry.";
+       
+       /* check for overlaps with other server NAT */
+       foreach ($a_snat as $natent) {
+               if (isset($id) && ($a_snat[$id]) && ($a_snat[$id] === $natent))
+                       continue;
+               
+               if ($_POST['ipaddr'] == $natent['ipaddr']) {
+                       $input_errors[] = "There is already a server NAT entry for the specified external IP address.";
+                       break;
+               }
+       }
+       
+       /* check for overlaps with 1:1 NAT */
+       if (is_array($config['nat']['onetoone'])) {
+               foreach ($config['nat']['onetoone'] as $natent) {
+                       if (check_subnets_overlap($_POST['ipaddr'], 32, $natent['external'], $natent['subnet'])) {
+                               $input_errors[] = "A 1:1 NAT mapping overlaps with the specified external IP address.";
+                               break;
+                       }
+               }
+       }
+
+       if (!$input_errors) {
+               $natent = array();
+               $natent['ipaddr'] = $_POST['ipaddr'];
+               $natent['descr'] = $_POST['descr'];
+               
+               if (isset($id) && $a_snat[$id])
+                       $a_snat[$id] = $natent;
+               else
+                       $a_snat[] = $natent;
+               
+               touch($d_natconfdirty_path);
+               
+               write_config();
+               
+               header("Location: firewall_nat_server.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: NAT: Edit Server NAT</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: NAT: Edit Server NAT</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="firewall_nat_server_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">External IP</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+                     
+                    </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_snat[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_rules.php b/webgui/firewall_rules.php
new file mode 100644 (file)
index 0000000..ed44d69
--- /dev/null
@@ -0,0 +1,242 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_rules.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['filter']['rule'])) {
+       $config['filter']['rule'] = array();
+}
+filter_rules_sort();
+$a_filter = &$config['filter']['rule'];
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = filter_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               if ($retval == 0) {
+                       if (file_exists($d_natconfdirty_path))
+                               unlink($d_natconfdirty_path);
+                       if (file_exists($d_filterconfdirty_path))
+                               unlink($d_filterconfdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_filter[$_GET['id']]) {
+               unset($a_filter[$_GET['id']]);
+               write_config();
+               touch($d_filterconfdirty_path);
+               header("Location: firewall_rules.php");
+               exit;
+       }
+} else if ($_GET['act'] == "down") {
+       if ($a_filter[$_GET['id']] && $a_filter[$_GET['id']+1]) {
+               $tmp = $a_filter[$_GET['id']+1];
+               $a_filter[$_GET['id']+1] = $a_filter[$_GET['id']];
+               $a_filter[$_GET['id']] = $tmp;
+               write_config();
+               touch($d_filterconfdirty_path);
+               header("Location: firewall_rules.php");
+               exit;
+       }
+} else if ($_GET['act'] == "up") {
+       if (($_GET['id'] > 0) && $a_filter[$_GET['id']]) {
+               $tmp = $a_filter[$_GET['id']-1];
+               $a_filter[$_GET['id']-1] = $a_filter[$_GET['id']];
+               $a_filter[$_GET['id']] = $tmp;
+               write_config();
+               touch($d_filterconfdirty_path);
+               header("Location: firewall_rules.php");
+               exit;
+       }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Rules</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Rules</p>
+<form action="firewall_rules.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_filterconfdirty_path)): ?><p>
+<?php print_info_box_np("The firewall rule configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <?php $lastif = ""; for ($i = 0; isset($a_filter[$i]); $i++):
+                               $filterent = $a_filter[$i];
+                if ($filterent['interface'] != $lastif):
+                if ($i):
+                               ?>
+                <tr>
+                  <td colspan="8" class="list" height="12"></td>
+                               </tr>
+                               <?php endif; ?>
+                <tr>
+                  <td colspan="7" class="listtopic"><?php
+                                 $iflabels = array('lan' => 'LAN interface', 'wan' => 'WAN interface', 'pptp' => 'PPTP clients');
+                                 for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+                                       $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['descr'] . " interface";
+                                 echo htmlspecialchars($iflabels[$filterent['interface']]); ?></td>
+                                 <td class="list"></td>
+                               </tr>
+                <tr>
+                  <td width="5%" class="list">&nbsp;</td>
+                  <td width="10%" class="listhdrr">Proto</td>
+                  <td width="15%" class="listhdrr">Source</td>
+                  <td width="10%" class="listhdrr">Port</td>
+                  <td width="15%" class="listhdrr">Destination</td>
+                  <td width="10%" class="listhdrr">Port</td>
+                  <td width="25%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                               <?php $lastif = $filterent['interface']; endif; ?>
+                <tr valign="top">
+                  <td class="listt">
+                                 <?php if ($filterent['type'] == "block")
+                                                       $iconfn = "block";
+                                               else if ($filterent['type'] == "reject") {
+                                                       if ($filterent['protocol'] == "tcp" || $filterent['protocol'] == "udp")
+                                                               $iconfn = "reject";
+                                                       else
+                                                               $iconfn = "block";
+                                               } else
+                                                       $iconfn = "pass";
+                                               if (isset($filterent['disabled']))
+                                                       $iconfn .= "_d";
+                                 ?>
+                                 <img src="<?=$iconfn;?>.gif" width="11" height="11">
+                                 <?php if (isset($filterent['log'])):
+                                                       $iconfn = "log_s";
+                                               if (isset($filterent['disabled']))
+                                                       $iconfn .= "_d";
+                                       ?>
+                                 <br><img src="<?=$iconfn;?>.gif" width="11" height="15">
+                                 <?php endif; ?>
+                                 </td>
+                  <td class="listlr"> 
+                    <?php if (isset($filterent['protocol'])) echo strtoupper($filterent['protocol']); else echo "*"; ?>
+                  </td>
+                  <td class="listr">
+                                   <?php echo htmlspecialchars(pprint_address($filterent['source'])); ?>
+                  </td>
+                  <td class="listr">
+                    <?php echo htmlspecialchars(pprint_port($filterent['source']['port'])); ?>
+                  </td>
+                  <td class="listr"> 
+                                   <?php echo htmlspecialchars(pprint_address($filterent['destination'])); ?>
+                  </td>
+                  <td class="listr"> 
+                    <?php echo htmlspecialchars(pprint_port($filterent['destination']['port'])); ?>
+                  </td>
+                  <td class="listbg"> 
+                    <?=htmlspecialchars($filterent['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" nowrap class="list">
+                                   <a href="firewall_rules_edit.php?id=<?=$i;?>"><img src="e.gif" alt="edit rule" width="17" height="17" border="0"></a>
+                                       <?php if (($i > 0) && ($a_filter[$i-1]['interface'] == $filterent['interface'])): ?>
+                                       <a href="firewall_rules.php?act=up&id=<?=$i;?>"><img src="up.gif" alt="move up" width="17" height="17" border="0"></a>
+                                       <?php else: ?>
+                                       <img src="up_d.gif" width="17" height="17" border="0">
+                                       <?php endif; ?><br>
+                                       <a href="firewall_rules.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this rule?')"><img src="x.gif" alt="delete rule" width="17" height="17" border="0"></a>
+                                       <?php if ($a_filter[$i+1]['interface'] == $filterent['interface']): ?>
+                                       <a href="firewall_rules.php?act=down&id=<?=$i;?>"><img src="down.gif" alt="move down" width="17" height="17" border="0"></a> 
+                    <?php else: ?>
+                                       <img src="down_d.gif" width="17" height="17" border="0">
+                                       <?php endif; ?>
+                                       <a href="firewall_rules_edit.php?dup=<?=$i;?>"><img src="plus.gif" alt="add a new rule based on this one" width="17" height="17" border="0"></a>
+                                 </td>
+                               </tr>
+                         <?php endfor; ?>
+                <tr> 
+                  <td class="list" colspan="7"></td>
+                  <td class="list"> <a href="firewall_rules_edit.php"><img src="plus.gif" alt="add new rule" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+                         <table border="0" cellspacing="0" cellpadding="0">
+                <tr> 
+                  <td width="16"><img src="pass.gif" width="11" height="11"></td>
+                  <td>pass</td>
+                  <td width="14"></td>
+                  <td width="16"><img src="block.gif" width="11" height="11"></td>
+                  <td>block</td>
+                  <td width="14"></td>
+                  <td width="16"><img src="reject.gif" width="11" height="11"></td>
+                  <td>reject</td>
+                  <td width="14"></td>
+                  <td width="16"><img src="log.gif" width="11" height="11"></td>
+                  <td>log</td>
+                </tr>
+                <tr>
+                  <td colspan="5" height="4"></td>
+                </tr>
+                <tr> 
+                  <td><img src="pass_d.gif" width="11" height="11"></td>
+                  <td>pass (disabled)</td>
+                  <td></td>
+                  <td><img src="block_d.gif" width="11" height="11"></td>
+                  <td>block (disabled)</td>
+                  <td></td>
+                  <td><img src="reject_d.gif" width="11" height="11"></td>
+                  <td>reject (disabled)</td>
+                  <td></td>
+                  <td width="16"><img src="log_d.gif" width="11" height="11"></td>
+                  <td>log (disabled)</td>
+                </tr>
+              </table>
+              <p>
+              <strong><span class="red">Hint:<br>
+              </span></strong>rules are evaluated on a first-match basis (i.e. 
+              the action of the first rule to match a packet will be executed). 
+              This means that if you use block rules, you'll have to pay attention 
+              to the rule order. Everything that isn't explicitly passed is blocked 
+              by default.</p>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_rules_edit.php b/webgui/firewall_rules_edit.php
new file mode 100644 (file)
index 0000000..ca78a7f
--- /dev/null
@@ -0,0 +1,691 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_rules_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$specialsrcdst = explode(" ", "any lan pptp");
+
+if (!is_array($config['filter']['rule'])) {
+       $config['filter']['rule'] = array();
+}
+filter_rules_sort();
+$a_filter = &$config['filter']['rule'];
+
+$id = $_GET['id'];
+if (is_numeric($_POST['id']))
+       $id = $_POST['id'];
+       
+$after = $_GET['after'];
+
+if (isset($_POST['after']))
+       $after = $_POST['after'];
+
+if (isset($_GET['dup'])) {
+       $id = $_GET['dup'];
+       $after = $_GET['dup'];
+}
+
+function is_specialnet($net) {
+       global $specialsrcdst;
+       
+       if (in_array($net, $specialsrcdst) || strstr($net, "opt"))
+               return true;
+       else
+               return false;
+}
+
+function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport) {
+               
+       if (isset($adr['any']))
+               $padr = "any";
+       else if ($adr['network'])
+               $padr = $adr['network'];
+       else if ($adr['address']) {
+               list($padr, $pmask) = explode("/", $adr['address']);
+               if (!$pmask)
+                       $pmask = 32;
+       }
+       
+       if (isset($adr['not']))
+               $pnot = 1;
+       else
+               $pnot = 0;
+       
+       if ($adr['port']) {
+               list($pbeginport, $pendport) = explode("-", $adr['port']);
+               if (!$pendport)
+                       $pendport = $pbeginport;
+       } else {
+               $pbeginport = "any";
+               $pendport = "any";
+       }
+}
+
+function pconfig_to_address(&$adr, $padr, $pmask, $pnot, $pbeginport, $pendport) {
+       
+       $adr = array();
+       
+       if ($padr == "any")
+               $adr['any'] = true;
+       else if (is_specialnet($padr))
+               $adr['network'] = $padr;
+       else {
+               $adr['address'] = $padr;
+               if ($pmask != 32)
+                       $adr['address'] .= "/" . $pmask;
+       }
+       
+       $adr['not'] = $pnot ? true : false;
+       
+       if (($pbeginport != 0) && ($pbeginport != "any")) {
+               if ($pbeginport != $pendport)
+                       $adr['port'] = $pbeginport . "-" . $pendport;
+               else
+                       $adr['port'] = $pbeginport;
+       }
+}
+
+if (isset($id) && $a_filter[$id]) {
+       $pconfig['interface'] = $a_filter[$id]['interface'];
+       
+       if (!isset($a_filter[$id]['type']))
+               $pconfig['type'] = "pass";
+       else
+               $pconfig['type'] = $a_filter[$id]['type'];
+       
+       if (isset($a_filter[$id]['protocol']))
+               $pconfig['proto'] = $a_filter[$id]['protocol'];
+       else
+               $pconfig['proto'] = "any";
+       
+       address_to_pconfig($a_filter[$id]['source'], $pconfig['src'],
+               $pconfig['srcmask'], $pconfig['srcnot'],
+               $pconfig['srcbeginport'], $pconfig['srcendport']);
+               
+       address_to_pconfig($a_filter[$id]['destination'], $pconfig['dst'],
+               $pconfig['dstmask'], $pconfig['dstnot'],
+               $pconfig['dstbeginport'], $pconfig['dstendport']);
+
+       $pconfig['disabled'] = isset($a_filter[$id]['disabled']);
+       $pconfig['log'] = isset($a_filter[$id]['log']);
+       $pconfig['frags'] = isset($a_filter[$id]['frags']);
+       $pconfig['descr'] = $a_filter[$id]['descr'];
+       
+} else {
+       /* defaults */
+       $pconfig['type'] = "pass";
+       $pconfig['src'] = "any";
+       $pconfig['dst'] = "any";
+}
+
+if (isset($_GET['dup']))
+       unset($id);
+
+if ($_POST) {
+
+       if (($_POST['proto'] != "tcp") && ($_POST['proto'] != "udp") && ($_POST['proto'] != "tcp/udp")) {
+               $_POST['srcbeginport'] = 0;
+               $_POST['srcendport'] = 0;
+               $_POST['dstbeginport'] = 0;
+               $_POST['dstendport'] = 0;
+       } else {
+       
+               if ($_POST['srcbeginport_cust'] && !$_POST['srcbeginport'])
+                       $_POST['srcbeginport'] = $_POST['srcbeginport_cust'];
+               if ($_POST['srcendport_cust'] && !$_POST['srcendport'])
+                       $_POST['srcendport'] = $_POST['srcendport_cust'];
+       
+               if ($_POST['srcbeginport'] == "any") {
+                       $_POST['srcbeginport'] = 0;
+                       $_POST['srcendport'] = 0;
+               } else {                        
+                       if (!$_POST['srcendport'])
+                               $_POST['srcendport'] = $_POST['srcbeginport'];
+               }
+               if ($_POST['srcendport'] == "any")
+                       $_POST['srcendport'] = $_POST['srcbeginport'];
+               
+               if ($_POST['dstbeginport_cust'] && !$_POST['dstbeginport'])
+                       $_POST['dstbeginport'] = $_POST['dstbeginport_cust'];
+               if ($_POST['dstendport_cust'] && !$_POST['dstendport'])
+                       $_POST['dstendport'] = $_POST['dstendport_cust'];
+               
+               if ($_POST['dstbeginport'] == "any") {
+                       $_POST['dstbeginport'] = 0;
+                       $_POST['dstendport'] = 0;
+               } else {                        
+                       if (!$_POST['dstendport'])
+                               $_POST['dstendport'] = $_POST['dstbeginport'];
+               }
+               if ($_POST['dstendport'] == "any")
+                       $_POST['dstendport'] = $_POST['dstbeginport'];          
+       }
+               
+       if (is_specialnet($_POST['srctype'])) {
+               $_POST['src'] = $_POST['srctype'];
+               $_POST['srcmask'] = 0;
+       } else if ($_POST['srctype'] == "single") {
+               $_POST['srcmask'] = 32;
+       }
+       if (is_specialnet($_POST['dsttype'])) {
+               $_POST['dst'] = $_POST['dsttype'];
+               $_POST['dstmask'] = 0;
+       }  else if ($_POST['dsttype'] == "single") {
+               $_POST['dstmask'] = 32;
+       }
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "type interface proto src dst");
+       $reqdfieldsn = explode(",", "Type,Interface,Protocol,Source,Destination");
+       
+       if (!(is_specialnet($_POST['srctype']) || ($_POST['srctype'] == "single"))) {
+               $reqdfields[] = "srcmask";
+               $reqdfieldsn[] = "Source bit count";
+       }
+       if (!(is_specialnet($_POST['dsttype']) || ($_POST['dsttype'] == "single"))) {
+               $reqdfields[] = "dstmask";
+               $reqdfieldsn[] = "Destination bit count";
+       }
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (!$_POST['srcbeginport']) {
+               $_POST['srcbeginport'] = 0;
+               $_POST['srcendport'] = 0;
+       }
+       if (!$_POST['dstbeginport']) {
+               $_POST['dstbeginport'] = 0;
+               $_POST['dstendport'] = 0;
+       }
+       
+       if (($_POST['srcbeginport'] && !is_port($_POST['srcbeginport']))) {
+               $input_errors[] = "The start source port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['srcendport'] && !is_port($_POST['srcendport']))) {
+               $input_errors[] = "The end source port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['dstbeginport'] && !is_port($_POST['dstbeginport']))) {
+               $input_errors[] = "The start destination port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['dstendport'] && !is_port($_POST['dstendport']))) {
+               $input_errors[] = "The end destination port must be an integer between 1 and 65535.";
+       }
+       
+       if (!is_specialnet($_POST['srctype'])) {
+               if (($_POST['src'] && !is_ipaddroranyalias($_POST['src']))) {
+                       $input_errors[] = "A valid source IP address or alias must be specified.";
+               }
+               if (($_POST['srcmask'] && !is_numericint($_POST['srcmask']))) {
+                       $input_errors[] = "A valid source bit count must be specified.";
+               }
+       }
+       if (!is_specialnet($_POST['dsttype'])) {
+               if (($_POST['dst'] && !is_ipaddroranyalias($_POST['dst']))) {
+                       $input_errors[] = "A valid destination IP address or alias must be specified.";
+               }
+               if (($_POST['dstmask'] && !is_numericint($_POST['dstmask']))) {
+                       $input_errors[] = "A valid destination bit count must be specified.";
+               }
+       }
+       
+       if ($_POST['srcbeginport'] > $_POST['srcendport']) {
+               /* swap */
+               $tmp = $_POST['srcendport'];
+               $_POST['srcendport'] = $_POST['srcbeginport'];
+               $_POST['srcbeginport'] = $tmp;
+       }
+       if ($_POST['dstbeginport'] > $_POST['dstendport']) {
+               /* swap */
+               $tmp = $_POST['dstendport'];
+               $_POST['dstendport'] = $_POST['dstbeginport'];
+               $_POST['dstbeginport'] = $tmp;
+       }
+
+       if (!$input_errors) {
+               $filterent = array();
+               $filterent['type'] = $_POST['type'];
+               $filterent['interface'] = $_POST['interface'];
+               
+               if ($_POST['proto'] != "any")
+                       $filterent['protocol'] = $_POST['proto'];
+               else
+                       unset($filterent['protocol']);
+               
+               pconfig_to_address($filterent['source'], $_POST['src'],
+                       $_POST['srcmask'], $_POST['srcnot'],
+                       $_POST['srcbeginport'], $_POST['srcendport']);
+                       
+               pconfig_to_address($filterent['destination'], $_POST['dst'],
+                       $_POST['dstmask'], $_POST['dstnot'],
+                       $_POST['dstbeginport'], $_POST['dstendport']);
+               
+               $filterent['disabled'] = $_POST['disabled'] ? true : false;
+               $filterent['log'] = $_POST['log'] ? true : false;
+               $filterent['frags'] = $_POST['frags'] ? true : false;
+               $filterent['descr'] = $_POST['descr'];
+               
+               if (isset($id) && $a_filter[$id])
+                       $a_filter[$id] = $filterent;
+               else {
+                       if (is_numeric($after))
+                               array_splice($a_filter, $after+1, 0, array($filterent));
+                       else
+                               $a_filter[] = $filterent;
+               }
+               
+               write_config();
+               touch($d_filterconfdirty_path);
+               
+               header("Location: firewall_rules.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Rules: Edit</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+var portsenabled = 1;
+
+function ext_change() {
+       if ((document.iform.srcbeginport.selectedIndex == 0) && portsenabled) {
+               document.iform.srcbeginport_cust.disabled = 0;
+       } else {
+               document.iform.srcbeginport_cust.value = "";
+               document.iform.srcbeginport_cust.disabled = 1;
+       }
+       if ((document.iform.srcendport.selectedIndex == 0) && portsenabled) {
+               document.iform.srcendport_cust.disabled = 0;
+       } else {
+               document.iform.srcendport_cust.value = "";
+               document.iform.srcendport_cust.disabled = 1;
+       }
+       if ((document.iform.dstbeginport.selectedIndex == 0) && portsenabled) {
+               document.iform.dstbeginport_cust.disabled = 0;
+       } else {
+               document.iform.dstbeginport_cust.value = "";
+               document.iform.dstbeginport_cust.disabled = 1;
+       }
+       if ((document.iform.dstendport.selectedIndex == 0) && portsenabled) {
+               document.iform.dstendport_cust.disabled = 0;
+       } else {
+               document.iform.dstendport_cust.value = "";
+               document.iform.dstendport_cust.disabled = 1;
+       }
+       
+       if (!portsenabled) {
+               document.iform.srcbeginport.disabled = 1;
+               document.iform.srcendport.disabled = 1;
+               document.iform.dstbeginport.disabled = 1;
+               document.iform.dstendport.disabled = 1;
+       } else {
+               document.iform.srcbeginport.disabled = 0;
+               document.iform.srcendport.disabled = 0;
+               document.iform.dstbeginport.disabled = 0;
+               document.iform.dstendport.disabled = 0;
+       }
+}
+
+function typesel_change() {
+       switch (document.iform.srctype.selectedIndex) {
+               case 1: /* single */
+                       document.iform.src.disabled = 0;
+                       document.iform.srcmask.value = "";
+                       document.iform.srcmask.disabled = 1;
+                       break;
+               case 2: /* network */
+                       document.iform.src.disabled = 0;
+                       document.iform.srcmask.disabled = 0;
+                       break;
+               default:
+                       document.iform.src.value = "";
+                       document.iform.src.disabled = 1;
+                       document.iform.srcmask.value = "";
+                       document.iform.srcmask.disabled = 1;
+                       break;
+       }
+       switch (document.iform.dsttype.selectedIndex) {
+               case 1: /* single */
+                       document.iform.dst.disabled = 0;
+                       document.iform.dstmask.value = "";
+                       document.iform.dstmask.disabled = 1;
+                       break;
+               case 2: /* network */
+                       document.iform.dst.disabled = 0;
+                       document.iform.dstmask.disabled = 0;
+                       break;
+               default:
+                       document.iform.dst.value = "";
+                       document.iform.dst.disabled = 1;
+                       document.iform.dstmask.value = "";
+                       document.iform.dstmask.disabled = 1;
+                       break;
+       }
+}
+
+function proto_change() {
+       if (document.iform.proto.selectedIndex < 3) {
+               portsenabled = 1;
+       } else {
+               portsenabled = 0;
+       }
+       
+       ext_change();
+}
+
+function src_rep_change() {
+       document.iform.srcendport.selectedIndex = document.iform.srcbeginport.selectedIndex;
+}
+function dst_rep_change() {
+       document.iform.dstendport.selectedIndex = document.iform.dstbeginport.selectedIndex;
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Rules: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="firewall_rules_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Action</td>
+                  <td width="78%" class="vtable">
+<select name="type" class="formfld">
+                      <?php $types = explode(" ", "Pass Block Reject"); foreach ($types as $type): ?>
+                      <option value="<?=strtolower($type);?>" <?php if (strtolower($type) == strtolower($pconfig['type'])) echo "selected"; ?>>
+                      <?=htmlspecialchars($type);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Choose what to do with packets that match
+                                       the criteria specified below.<br>
+Hint: the difference between block and reject is that with reject, a packet (TCP RST or ICMP port unreachable for UDP) is returned to the sender, whereas with block the packet is dropped silently. In either case, the original packet is discarded. Reject only works when the protocol is set to either TCP or UDP (but not &quot;TCP/UDP&quot;) below.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Disabled</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>>
+                    <strong>Disable this rule</strong><br>
+                    <span class="vexpl">Set this option to disable this rule without
+                                       removing it from the list.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Interface</td>
+                  <td width="78%" class="vtable">
+<select name="interface" class="formfld">
+                      <?php $interfaces = array('wan' => 'WAN', 'lan' => 'LAN', 'pptp' => 'PPTP');
+                                         for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                                               $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+                                         }
+                                         foreach ($interfaces as $iface => $ifacename): ?>
+                      <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>>
+                      <?=htmlspecialchars($ifacename);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Choose on which interface packets must 
+                    come in to match this rule.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
+                  <td width="78%" class="vtable">
+<select name="proto" class="formfld" onchange="proto_change()">
+                      <?php $protocols = explode(" ", "TCP UDP TCP/UDP ICMP ESP AH GRE IPv6 any"); foreach ($protocols as $proto): ?>
+                      <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>>
+                      <?=htmlspecialchars($proto);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Choose which IP protocol this rule should 
+                    match.<br>
+                    Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Source</td>
+                  <td width="78%" class="vtable">
+<input name="srcnot" type="checkbox" id="srcnot" value="yes" <?php if ($pconfig['srcnot']) echo "checked"; ?>>
+                    <strong>not</strong><br>
+                    Use this option to invert the sense of the match.<br>
+                    <br>
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>Type:&nbsp;&nbsp;</td>
+                        <td><select name="srctype" class="formfld" onChange="typesel_change()">
+                                                       <?php $sel = is_specialnet($pconfig['src']); ?>
+                            <option value="any" <?php if ($pconfig['src'] == "any") { echo "selected"; } ?>>
+                            any</option>
+                            <option value="single" <?php if (($pconfig['srcmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>
+                            Single host or alias</option>
+                            <option value="network" <?php if (!$sel) echo "selected"; ?>>
+                            Network</option>
+                            <option value="lan" <?php if ($pconfig['src'] == "lan") { echo "selected"; } ?>>
+                            LAN subnet</option>
+                            <option value="pptp" <?php if ($pconfig['src'] == "pptp") { echo "selected"; } ?>>
+                            PPTP clients</option>
+                                                       <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+                            <option value="opt<?=$i;?>" <?php if ($pconfig['src'] == "opt" . $i) { echo "selected"; } ?>>
+                            <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?> subnet</option>
+                                                       <?php endfor; ?>
+                          </select></td>
+                      </tr>
+                      <tr> 
+                        <td>Address:&nbsp;&nbsp;</td>
+                        <td><input name="src" type="text" class="formfldalias" id="src" size="20" value="<?php if (!is_specialnet($pconfig['src'])) echo htmlspecialchars($pconfig['src']);?>">
+                        /
+                                               <select name="srcmask" class="formfld" id="srcmask">
+                                               <?php for ($i = 31; $i > 0; $i--): ?>
+                                               <option value="<?=$i;?>" <?php if ($i == $pconfig['srcmask']) echo "selected"; ?>><?=$i;?></option>
+                                               <?php endfor; ?>
+                                               </select>
+                                               </td>
+                                         </tr>
+                    </table></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Source port range 
+                  </td>
+                  <td width="78%" class="vtable"> 
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>from:&nbsp;&nbsp;</td>
+                        <td><select name="srcbeginport" class="formfld" onchange="src_rep_change();ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['srcbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcbeginport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>>
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="srcbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcbeginport']) echo $pconfig['srcbeginport']; ?>"></td>
+                      </tr>
+                      <tr> 
+                        <td>to:</td>
+                        <td><select name="srcendport" class="formfld" onchange="ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['srcendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcendport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>>
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="srcendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcendport']) echo $pconfig['srcendport']; ?>"></td>
+                      </tr>
+                    </table>
+                    <br> <span class="vexpl">Specify the port or port range for 
+                    the source of the packet for this rule.<br>
+                    Hint: you can leave the <em>'to'</em> field empty if you only 
+                    want to filter a single port</span></td>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Destination</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="dstnot" type="checkbox" id="dstnot" value="yes" <?php if ($pconfig['dstnot']) echo "checked"; ?>> 
+                    <strong>not</strong><br>
+                    Use this option to invert the sense of the match.<br>
+                    <br>
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>Type:&nbsp;&nbsp;</td>
+                        <td><select name="dsttype" class="formfld" onChange="typesel_change()">
+                            <?php $sel = is_specialnet($pconfig['dst']); ?>
+                            <option value="any" <?php if ($pconfig['dst'] == "any") { echo "selected"; } ?>>
+                            any</option>
+                            <option value="single" <?php if (($pconfig['dstmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>>
+                            Single host or alias</option>
+                            <option value="network" <?php if (!$sel) echo "selected"; ?>>
+                            Network</option>
+                            <option value="lan" <?php if ($pconfig['dst'] == "lan") { echo "selected"; } ?>>
+                            LAN subnet</option>
+                            <option value="pptp" <?php if ($pconfig['dst'] == "pptp") { echo "selected"; } ?>>
+                            PPTP clients</option>
+                                                       <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+                            <option value="opt<?=$i;?>" <?php if ($pconfig['dst'] == "opt" . $i) { echo "selected"; } ?>>
+                            <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?> subnet</option>
+                                                       <?php endfor; ?>
+                          </select></td>
+                      </tr>
+                      <tr> 
+                        <td>Address:&nbsp;&nbsp;</td>
+                        <td><input name="dst" type="text" class="formfldalias" id="dst" size="20" value="<?php if (!is_specialnet($pconfig['dst'])) echo htmlspecialchars($pconfig['dst']);?>">
+                          / 
+                          <select name="dstmask" class="formfld" id="dstmask">
+                                               <?php for ($i = 31; $i > 0; $i--): ?>
+                                               <option value="<?=$i;?>" <?php if ($i == $pconfig['dstmask']) echo "selected"; ?>><?=$i;?></option>
+                                               <?php endfor; ?>
+                                               </select></td>
+                      </tr>
+                    </table></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Destination port 
+                    range </td>
+                  <td width="78%" class="vtable"> 
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>from:&nbsp;&nbsp;</td>
+                        <td><select name="dstbeginport" class="formfld" onchange="dst_rep_change();ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['dstbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstbeginport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>>
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="dstbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstbeginport']) echo $pconfig['dstbeginport']; ?>"></td>
+                      </tr>
+                      <tr> 
+                        <td>to:</td>
+                        <td><select name="dstendport" class="formfld" onchange="ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['dstendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstendport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>>
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="dstendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstendport']) echo $pconfig['dstendport']; ?>"></td>
+                      </tr>
+                    </table>
+                    <br> <span class="vexpl">Specify the port or port range for 
+                    the destination of the packet for this rule.<br>
+                    Hint: you can leave the <em>'to'</em> field empty if you only 
+                    want to filter a single port</span></td>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Fragments</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="frags" type="checkbox" id="frags" value="yes" <?php if ($pconfig['frags']) echo "checked"; ?>>
+                    <strong>Allow fragmented packets</strong><br>
+                    <span class="vexpl">Hint: this option puts additional load 
+                    on the firewall and may make it vulnerable to DoS attacks. 
+                    In most cases, it is not needed. Try enabling it if you have 
+                    troubles connecting to certain sites.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Log</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="log" type="checkbox" id="log" value="yes" <?php if ($pconfig['log']) echo "checked"; ?>>
+                    <strong>Log packets that are handled by this rule</strong><br>
+                    <span class="vexpl">Hint: the firewall has limited local log 
+                    space. Don't turn on logging for everything. If you want to 
+                    do a lot of logging, consider using a remote syslog server 
+                    (see the <a href="diag_logs_settings.php">Diagnostics: System 
+                    logs: Settings</a> page).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_filter[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                    <input name="after" type="hidden" value="<?=$after;?>"> 
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+ext_change();
+typesel_change();
+proto_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_shaper.php b/webgui/firewall_shaper.php
new file mode 100644 (file)
index 0000000..8288402
--- /dev/null
@@ -0,0 +1,225 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_shaper.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['shaper']['rule'])) {
+       $config['shaper']['rule'] = array();
+}
+$a_shaper = &$config['shaper']['rule'];
+
+$pconfig['enable'] = isset($config['shaper']['enable']);
+
+if ($_POST) {
+
+       if ($_POST['submit']) {
+               $pconfig = $_POST;
+               $config['shaper']['enable'] = $_POST['enable'] ? true : false;
+               write_config();
+       }
+       
+       if ($_POST['apply'] || $_POST['submit']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = shaper_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               if ($retval == 0) {
+                       if (file_exists($d_shaperconfdirty_path))
+                               unlink($d_shaperconfdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_shaper[$_GET['id']]) {
+               unset($a_shaper[$_GET['id']]);
+               write_config();
+               touch($d_shaperconfdirty_path);
+               header("Location: firewall_shaper.php");
+               exit;
+       }
+} else if ($_GET['act'] == "down") {
+       if ($a_shaper[$_GET['id']] && $a_shaper[$_GET['id']+1]) {
+               $tmp = $a_shaper[$_GET['id']+1];
+               $a_shaper[$_GET['id']+1] = $a_shaper[$_GET['id']];
+               $a_shaper[$_GET['id']] = $tmp;
+               write_config();
+               touch($d_shaperconfdirty_path);
+               header("Location: firewall_shaper.php");
+               exit;
+       }
+} else if ($_GET['act'] == "up") {
+       if (($_GET['id'] > 0) && $a_shaper[$_GET['id']]) {
+               $tmp = $a_shaper[$_GET['id']-1];
+               $a_shaper[$_GET['id']-1] = $a_shaper[$_GET['id']];
+               $a_shaper[$_GET['id']] = $tmp;
+               write_config();
+               touch($d_shaperconfdirty_path);
+               header("Location: firewall_shaper.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Traffic shaper</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper</p>
+<form action="firewall_shaper.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabact">Rules</td>
+    <td nowrap class="tabinact"><a href="firewall_shaper_pipes.php" class="tblnk">Pipes</a></td>
+    <td nowrap class="tabinact"><a href="firewall_shaper_queues.php" class="tblnk">Queues</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="4" class="tabcont">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td class="vtable"><p>
+                      <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable'] == "yes") echo "checked";?>>
+                      <strong>Enable traffic shaper<br>
+                      </strong></p></td>
+                </tr>
+                <tr> 
+                  <td> <input name="submit" type="submit" class="formbtn" value="Save"> 
+                  </td>
+                </tr>
+              </table>
+              &nbsp;<br>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                      <tr> 
+                        <td width="5%" class="listhdrrns">If</td>
+                        <td width="5%" class="listhdrrns">Proto</td>
+                        <td width="20%" class="listhdrr">Source</td>
+                        <td width="20%" class="listhdrr">Destination</td>
+                        <td width="15%" class="listhdrrns">Target</td>
+                        <td width="25%" class="listhdr">Description</td>
+                        <td width="10%" class="list"></td>
+                      </tr>
+                      <?php $i = 0; foreach ($a_shaper as $shaperent): ?>
+                      <tr valign="top"> 
+                        <td class="listlr"> 
+                          <?php
+                                 $iflabels = array('lan' => 'LAN', 'wan' => 'WAN', 'pptp' => 'PPTP');
+                                 for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+                                       $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+                                 echo htmlspecialchars($iflabels[$shaperent['interface']]);
+                                 if ($shaperent['direction'])
+                                       echo "<br><img src=\"{$shaperent['direction']}.gif\" width=\"11\" height=\"11\" style=\"margin-top: 5px\">";
+                                 ?>
+                        </td>
+                        <td class="listr"> 
+                          <?php if (isset($shaperent['protocol'])) echo strtoupper($shaperent['protocol']); else echo "*"; ?>
+                        </td>
+                        <td class="listr"> <?php echo htmlspecialchars(pprint_address($shaperent['source'])); ?>
+                                               <?php if ($shaperent['source']['port']): ?><br>
+                                               Port: <?=htmlspecialchars(pprint_port($shaperent['source']['port'])); ?> 
+                                               <?php endif; ?>
+                        </td>
+                        <td class="listr"> <?php echo htmlspecialchars(pprint_address($shaperent['destination'])); ?>
+                                               <?php if ($shaperent['destination']['port']): ?><br>
+                                               Port: <?=htmlspecialchars(pprint_port($shaperent['destination']['port'])); ?>
+                                               <?php endif; ?>
+                        </td>
+                        <td class="listr"> 
+                          <?php 
+                                               if (isset($shaperent['targetpipe']))
+                                                       echo "<a href=\"firewall_shaper_pipes_edit.php?id={$shaperent['targetpipe']}\">Pipe " . 
+                                                               ($shaperent['targetpipe']+1) . "</a>";
+                                               else if (isset($shaperent['targetqueue']))
+                                                       echo "<a href=\"firewall_shaper_queues_edit.php?id={$shaperent['targetqueue']}\">Queue " . 
+                                                               ($shaperent['targetqueue']+1) . "</a>";
+                                       ?>
+                        </td>
+                        <td class="listbg"> 
+                          <?=htmlspecialchars($shaperent['descr']);?>
+                          &nbsp; </td>
+                        <td valign="middle" nowrap class="list"> <a href="firewall_shaper_edit.php?id=<?=$i;?>"><img src="e.gif" alt="edit rule" width="17" height="17" border="0"></a> 
+                          <?php if ($i > 0): ?>
+                          <a href="firewall_shaper.php?act=up&id=<?=$i;?>"><img src="up.gif" alt="move up" width="17" height="17" border="0"></a> 
+                          <?php else: ?>
+                          <img src="up_d.gif" width="17" height="17" border="0"> 
+                          <?php endif; ?><br>
+                                                 <a href="firewall_shaper.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this rule?')"><img src="x.gif" alt="delete rule" width="17" height="17" border="0"></a> 
+                          <?php if (isset($a_shaper[$i+1])): ?>
+                          <a href="firewall_shaper.php?act=down&id=<?=$i;?>"><img src="down.gif" alt="move down" width="17" height="17" border="0"></a> 
+                          <?php else: ?>
+                          <img src="down_d.gif" width="17" height="17" border="0"> 
+                          <?php endif; ?>
+                          <a href="firewall_shaper_edit.php?dup=<?=$i;?>"><img src="plus.gif" alt="add a new rule based on this one" width="17" height="17" border="0"></a> 
+                        </td>
+                      </tr>
+                      <?php $i++; endforeach; ?>
+                      <tr> 
+                        <td class="list" colspan="6"></td>
+                        <td class="list"> <a href="firewall_shaper_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                      </tr>
+                    </table>
+                                         
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td width="16"><img src="in.gif" width="11" height="11"></td>
+                        <td>incoming (as seen by firewall)</td>
+                      </tr>
+                      <tr> 
+                        <td colspan="5" height="4"></td>
+                      </tr>
+                      <tr> 
+                        <td><img src="out.gif" width="11" height="11"></td>
+                        <td>outgoing (as seen by firewall)</td>
+                      </tr>
+                    </table>
+                               <p><span class="red"><strong>Note:</strong></span><strong><br>
+                    </strong>the first rule that matches a packet will be executed.<br>
+                    The following match patterns are not shown in the list above: 
+                    IP packet length, TCP flags.</td></p>
+       </tr>
+</table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_shaper_edit.php b/webgui/firewall_shaper_edit.php
new file mode 100644 (file)
index 0000000..14b39f5
--- /dev/null
@@ -0,0 +1,735 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_shaper_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['shaper']['rule'])) {
+       $config['shaper']['rule'] = array();
+}
+$a_shaper = &$config['shaper']['rule'];
+
+$specialsrcdst = explode(" ", "any lan pptp");
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+       
+$after = $_GET['after'];
+if (isset($_POST['after']))
+       $after = $_POST['after'];
+       
+if (isset($_GET['dup'])) {
+       $id = $_GET['dup'];
+       $after = $_GET['dup'];
+}
+       
+function is_specialnet($net) {
+       global $specialsrcdst;
+       
+       if (in_array($net, $specialsrcdst) || strstr($net, "opt"))
+               return true;
+       else
+               return false;
+}
+       
+function address_to_pconfig($adr, &$padr, &$pmask, &$pnot, &$pbeginport, &$pendport) {
+               
+       if (isset($adr['any']))
+               $padr = "any";
+       else if ($adr['network'])
+               $padr = $adr['network'];
+       else if ($adr['address']) {
+               list($padr, $pmask) = explode("/", $adr['address']);
+               if (!$pmask)
+                       $pmask = 32;
+       }
+       
+       if (isset($adr['not']))
+               $pnot = 1;
+       else
+               $pnot = 0;
+       
+       if ($adr['port']) {
+               list($pbeginport, $pendport) = explode("-", $adr['port']);
+               if (!$pendport)
+                       $pendport = $pbeginport;
+       } else {
+               $pbeginport = "any";
+               $pendport = "any";
+       }
+}
+
+function pconfig_to_address(&$adr, $padr, $pmask, $pnot, $pbeginport, $pendport) {
+       
+       $adr = array();
+       
+       if ($padr == "any")
+               $adr['any'] = true;
+       else if (is_specialnet($padr))
+               $adr['network'] = $padr;
+       else {
+               $adr['address'] = $padr;
+               if ($pmask != 32)
+                       $adr['address'] .= "/" . $pmask;
+       }
+       
+       $adr['not'] = $pnot ? true : false;
+       
+       if (($pbeginport != 0) && ($pbeginport != "any")) {
+               if ($pbeginport != $pendport)
+                       $adr['port'] = $pbeginport . "-" . $pendport;
+               else
+                       $adr['port'] = $pbeginport;
+       }
+}
+
+if (isset($id) && $a_shaper[$id]) {
+       $pconfig['interface'] = $a_shaper[$id]['interface'];
+       
+       if (isset($a_shaper[$id]['protocol']))
+               $pconfig['proto'] = $a_shaper[$id]['protocol'];
+       else
+               $pconfig['proto'] = "any";
+       
+       address_to_pconfig($a_shaper[$id]['source'], $pconfig['src'],
+               $pconfig['srcmask'], $pconfig['srcnot'],
+               $pconfig['srcbeginport'], $pconfig['srcendport']);
+               
+       address_to_pconfig($a_shaper[$id]['destination'], $pconfig['dst'],
+               $pconfig['dstmask'], $pconfig['dstnot'],
+               $pconfig['dstbeginport'], $pconfig['dstendport']);
+       
+       if (isset($a_shaper[$id]['targetpipe'])) {
+               $pconfig['target'] = "targetpipe:" . $a_shaper[$id]['targetpipe'];
+       } else if (isset($a_shaper[$id]['targetqueue'])) {
+               $pconfig['target'] = "targetqueue:" . $a_shaper[$id]['targetqueue'];
+       }
+       
+       $pconfig['direction'] = $a_shaper[$id]['direction'];
+       $pconfig['iplen'] = $a_shaper[$id]['iplen'];
+       $pconfig['tcpflags'] = $a_shaper[$id]['tcpflags'];
+       $pconfig['descr'] = $a_shaper[$id]['descr'];
+       
+       if ($pconfig['srcbeginport'] == 0) {
+               $pconfig['srcbeginport'] = "any";
+               $pconfig['srcendport'] = "any";
+       }
+       if ($pconfig['dstbeginport'] == 0) {
+               $pconfig['dstbeginport'] = "any";
+               $pconfig['dstendport'] = "any";
+       }
+       
+} else {
+       /* defaults */
+       $pconfig['src'] = "any";
+       $pconfig['dst'] = "any";
+}
+
+if (isset($_GET['dup']))
+       unset($id);
+
+if ($_POST) {
+
+       if (($_POST['proto'] != "tcp") && ($_POST['proto'] != "udp") && ($_POST['proto'] != "tcp/udp")) {
+               $_POST['srcbeginport'] = 0;
+               $_POST['srcendport'] = 0;
+               $_POST['dstbeginport'] = 0;
+               $_POST['dstendport'] = 0;
+       } else {
+       
+               if ($_POST['srcbeginport_cust'] && !$_POST['srcbeginport'])
+                       $_POST['srcbeginport'] = $_POST['srcbeginport_cust'];
+               if ($_POST['srcendport_cust'] && !$_POST['srcendport'])
+                       $_POST['srcendport'] = $_POST['srcendport_cust'];
+       
+               if ($_POST['srcbeginport'] == "any") {
+                       $_POST['srcbeginport'] = 0;
+                       $_POST['srcendport'] = 0;
+               } else {                        
+                       if (!$_POST['srcendport'])
+                               $_POST['srcendport'] = $_POST['srcbeginport'];
+               }
+               if ($_POST['srcendport'] == "any")
+                       $_POST['srcendport'] = $_POST['srcbeginport'];
+               
+               if ($_POST['dstbeginport_cust'] && !$_POST['dstbeginport'])
+                       $_POST['dstbeginport'] = $_POST['dstbeginport_cust'];
+               if ($_POST['dstendport_cust'] && !$_POST['dstendport'])
+                       $_POST['dstendport'] = $_POST['dstendport_cust'];
+               
+               if ($_POST['dstbeginport'] == "any") {
+                       $_POST['dstbeginport'] = 0;
+                       $_POST['dstendport'] = 0;
+               } else {                        
+                       if (!$_POST['dstendport'])
+                               $_POST['dstendport'] = $_POST['dstbeginport'];
+               }
+               if ($_POST['dstendport'] == "any")
+                       $_POST['dstendport'] = $_POST['dstbeginport'];          
+       }
+               
+       if (is_specialnet($_POST['srctype'])) {
+               $_POST['src'] = $_POST['srctype'];
+               $_POST['srcmask'] = 0;
+       } else if ($_POST['srctype'] == "single") {
+               $_POST['srcmask'] = 32;
+       }
+       if (is_specialnet($_POST['dsttype'])) {
+               $_POST['dst'] = $_POST['dsttype'];
+               $_POST['dstmask'] = 0;
+       }  else if ($_POST['dsttype'] == "single") {
+               $_POST['dstmask'] = 32;
+       }
+       
+       $intcpflags = array();
+       foreach ($tcpflags as $tcpflag) {
+               if ($_POST['tcpflags_' . $tcpflag] == "on")
+                       $intcpflags[] = $tcpflag;
+               else if ($_POST['tcpflags_' . $tcpflag] == "off")
+                       $intcpflags[] = "!" . $tcpflag;
+       }
+       $_POST['tcpflags'] = join(",", $intcpflags);
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "target proto src dst");
+       $reqdfieldsn = explode(",", "Target,Protocol,Source,Destination");
+       
+       if (!(is_specialnet($_POST['srctype']) || ($_POST['srctype'] == "single"))) {
+               $reqdfields[] = "srcmask";
+               $reqdfieldsn[] = "Source bit count";
+       }
+       if (!(is_specialnet($_POST['dsttype']) || ($_POST['dsttype'] == "single"))) {
+               $reqdfields[] = "dstmask";
+               $reqdfieldsn[] = "Destination bit count";
+       }
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (!$_POST['srcbeginport']) {
+               $_POST['srcbeginport'] = 0;
+               $_POST['srcendport'] = 0;
+       }
+       if (!$_POST['dstbeginport']) {
+               $_POST['dstbeginport'] = 0;
+               $_POST['dstendport'] = 0;
+       }
+       
+       if (($_POST['srcbeginport'] && !is_port($_POST['srcbeginport']))) {
+               $input_errors[] = "The start source port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['srcendport'] && !is_port($_POST['srcendport']))) {
+               $input_errors[] = "The end source port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['dstbeginport'] && !is_port($_POST['dstbeginport']))) {
+               $input_errors[] = "The start destination port must be an integer between 1 and 65535.";
+       }
+       if (($_POST['dstendport'] && !is_port($_POST['dstendport']))) {
+               $input_errors[] = "The end destination port must be an integer between 1 and 65535.";
+       }
+       
+       if (!is_specialnet($_POST['srctype'])) {
+               if (($_POST['src'] && !is_ipaddroranyalias($_POST['src']))) {
+                       $input_errors[] = "A valid source IP address or alias must be specified.";
+               }
+               if (($_POST['srcmask'] && !is_numericint($_POST['srcmask']))) {
+                       $input_errors[] = "A valid source bit count must be specified.";
+               }
+       }
+       if (!is_specialnet($_POST['dsttype'])) {
+               if (($_POST['dst'] && !is_ipaddroranyalias($_POST['dst']))) {
+                       $input_errors[] = "A valid destination IP address or alias must be specified.";
+               }
+               if (($_POST['dstmask'] && !is_numericint($_POST['dstmask']))) {
+                       $input_errors[] = "A valid destination bit count must be specified.";
+               }
+       }
+       
+       if ($_POST['srcbeginport'] > $_POST['srcendport']) {
+               /* swap */
+               $tmp = $_POST['srcendport'];
+               $_POST['srcendport'] = $_POST['srcbeginport'];
+               $_POST['srcbeginport'] = $tmp;
+       }
+       if ($_POST['dstbeginport'] > $_POST['dstendport']) {
+               /* swap */
+               $tmp = $_POST['dstendport'];
+               $_POST['dstendport'] = $_POST['dstbeginport'];
+               $_POST['dstbeginport'] = $tmp;
+       }
+       
+       if (($_POST['iplen'] && !preg_match("/^(\d+)(-(\d+))?$/", $_POST['iplen']))) {
+               $input_errors[] = "The IP packet length must be an integer or a range (from-to).";
+       }
+
+       if (!$input_errors) {
+               $shaperent = array();
+               $shaperent['interface'] = $_POST['interface'];
+               
+               if ($_POST['proto'] != "any")
+                       $shaperent['protocol'] = $_POST['proto'];
+               else
+                       unset($shaperent['protocol']);
+               
+               pconfig_to_address($shaperent['source'], $_POST['src'],
+                       $_POST['srcmask'], $_POST['srcnot'],
+                       $_POST['srcbeginport'], $_POST['srcendport']);
+                       
+               pconfig_to_address($shaperent['destination'], $_POST['dst'],
+                       $_POST['dstmask'], $_POST['dstnot'],
+                       $_POST['dstbeginport'], $_POST['dstendport']);
+               
+               $shaperent['direction'] = $_POST['direction'];
+               $shaperent['iplen'] = $_POST['iplen'];
+               $shaperent['tcpflags'] = $_POST['tcpflags'];
+               $shaperent['descr'] = $_POST['descr'];
+               
+               list($targettype,$target) = explode(":", $_POST['target']);
+               $shaperent[$targettype] = $target;
+               
+               if (isset($id) && $a_shaper[$id])
+                       $a_shaper[$id] = $shaperent;
+               else {
+                       if (is_numeric($after))
+                               array_splice($a_shaper, $after+1, 0, array($shaperent));
+                       else
+                               $a_shaper[] = $shaperent;
+               }
+               
+               write_config();
+               touch($d_shaperconfdirty_path);
+               
+               header("Location: firewall_shaper.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Traffic shaper: Edit rule</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+var portsenabled = 1;
+
+function ext_change() {
+       if ((document.iform.srcbeginport.selectedIndex == 0) && portsenabled) {
+               document.iform.srcbeginport_cust.disabled = 0;
+       } else {
+               document.iform.srcbeginport_cust.value = "";
+               document.iform.srcbeginport_cust.disabled = 1;
+       }
+       if ((document.iform.srcendport.selectedIndex == 0) && portsenabled) {
+               document.iform.srcendport_cust.disabled = 0;
+       } else {
+               document.iform.srcendport_cust.value = "";
+               document.iform.srcendport_cust.disabled = 1;
+       }
+       if ((document.iform.dstbeginport.selectedIndex == 0) && portsenabled) {
+               document.iform.dstbeginport_cust.disabled = 0;
+       } else {
+               document.iform.dstbeginport_cust.value = "";
+               document.iform.dstbeginport_cust.disabled = 1;
+       }
+       if ((document.iform.dstendport.selectedIndex == 0) && portsenabled) {
+               document.iform.dstendport_cust.disabled = 0;
+       } else {
+               document.iform.dstendport_cust.value = "";
+               document.iform.dstendport_cust.disabled = 1;
+       }
+       
+       if (!portsenabled) {
+               document.iform.srcbeginport.disabled = 1;
+               document.iform.srcendport.disabled = 1;
+               document.iform.dstbeginport.disabled = 1;
+               document.iform.dstendport.disabled = 1;
+       } else {
+               document.iform.srcbeginport.disabled = 0;
+               document.iform.srcendport.disabled = 0;
+               document.iform.dstbeginport.disabled = 0;
+               document.iform.dstendport.disabled = 0;
+       }
+}
+
+function typesel_change() {
+       switch (document.iform.srctype.selectedIndex) {
+               case 1: /* single */
+                       document.iform.src.disabled = 0;
+                       document.iform.srcmask.value = "";
+                       document.iform.srcmask.disabled = 1;
+                       break;
+               case 2: /* network */
+                       document.iform.src.disabled = 0;
+                       document.iform.srcmask.disabled = 0;
+                       break;
+               default:
+                       document.iform.src.value = "";
+                       document.iform.src.disabled = 1;
+                       document.iform.srcmask.value = "";
+                       document.iform.srcmask.disabled = 1;
+                       break;
+       }
+       switch (document.iform.dsttype.selectedIndex) {
+               case 1: /* single */
+                       document.iform.dst.disabled = 0;
+                       document.iform.dstmask.value = "";
+                       document.iform.dstmask.disabled = 1;
+                       break;
+               case 2: /* network */
+                       document.iform.dst.disabled = 0;
+                       document.iform.dstmask.disabled = 0;
+                       break;
+               default:
+                       document.iform.dst.value = "";
+                       document.iform.dst.disabled = 1;
+                       document.iform.dstmask.value = "";
+                       document.iform.dstmask.disabled = 1;
+                       break;
+       }
+}
+
+function proto_change() {
+       if (document.iform.proto.selectedIndex < 3) {
+               portsenabled = 1;
+       } else {
+               portsenabled = 0;
+       }
+       
+       ext_change();
+}
+
+function src_rep_change() {
+       document.iform.srcendport.selectedIndex = document.iform.srcbeginport.selectedIndex;
+}
+function dst_rep_change() {
+       document.iform.dstendport.selectedIndex = document.iform.dstbeginport.selectedIndex;
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper: Edit rule</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+<?php if (is_array($config['shaper']['pipe']) && (count($config['shaper']['pipe']) > 0)): ?>
+            <form action="firewall_shaper_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td valign="top" class="vncellreq">Target</td>
+                  <td class="vtable"> <select name="target" class="formfld">
+                      <?php 
+                                         foreach ($config['shaper']['pipe'] as $pipei => $pipe): ?>
+                      <option value="<?="targetpipe:$pipei";?>" <?php if ("targetpipe:$pipei" == $pconfig['target']) echo "selected"; ?>> 
+                      <?php
+                                               echo htmlspecialchars("Pipe " . ($pipei + 1));
+                                               if ($pipe['descr'])
+                                                       echo htmlspecialchars(" (" . $pipe['descr'] . ")");
+                                         ?>
+                      </option>
+                      <?php endforeach;
+                                         foreach ($config['shaper']['queue'] as $queuei => $queue): ?>
+                      <option value="<?="targetqueue:$queuei";?>" <?php if ("targetqueue:$queuei" == $pconfig['target']) echo "selected"; ?>> 
+                      <?php
+                                               echo htmlspecialchars("Queue " . ($queuei + 1));
+                                               if ($queue['descr'])
+                                                       echo htmlspecialchars(" (" . $queue['descr'] . ")");
+                                         ?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Choose a pipe or queue where packets that 
+                    match this rule should be sent.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Interface</td>
+                  <td width="78%" class="vtable"> <select name="interface" class="formfld">
+                      <?php $interfaces = array('lan' => 'LAN', 'wan' => 'WAN', 'pptp' => 'PPTP');
+                                         for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                                               $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+                                         }
+                                         foreach ($interfaces as $iface => $ifacename): ?>
+                      <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($ifacename);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Choose which interface packets must pass 
+                    through to match this rule.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
+                  <td width="78%" class="vtable"> <select name="proto" class="formfld" onchange="proto_change()">
+                      <?php $protocols = explode(" ", "TCP UDP ICMP ESP AH GRE IPv6 any"); foreach ($protocols as $proto): ?>
+                      <option value="<?=strtolower($proto);?>" <?php if (strtolower($proto) == $pconfig['proto']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($proto);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Choose which IP protocol 
+                    this rule should match.<br>
+                    Hint: in most cases, you should specify <em>TCP</em> &nbsp;here.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Source</td>
+                  <td width="78%" class="vtable"> <input name="srcnot" type="checkbox" id="srcnot" value="yes" <?php if ($pconfig['srcnot']) echo "checked"; ?>> 
+                    <strong>not</strong><br>
+                    Use this option to invert the sense of the match.<br> <br> 
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>Type:&nbsp;&nbsp;</td>
+                        <td><select name="srctype" class="formfld" onChange="typesel_change()">
+                            <?php $sel = is_specialnet($pconfig['src']); ?>
+                            <option value="any" <?php if ($pconfig['src'] == "any") { echo "selected"; } ?>> 
+                            any</option>
+                            <option value="single" <?php if (($pconfig['srcmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>> 
+                            Single host or alias</option>
+                            <option value="network" <?php if (!$sel) echo "selected"; ?>> 
+                            Network</option>
+                            <option value="lan" <?php if ($pconfig['src'] == "lan") { echo "selected"; } ?>> 
+                            LAN subnet</option>
+                            <option value="pptp" <?php if ($pconfig['src'] == "pptp") { echo "selected"; } ?>> 
+                            PPTP clients</option>
+                            <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+                            <option value="opt<?=$i;?>" <?php if ($pconfig['src'] == "opt" . $i) { echo "selected"; } ?>> 
+                            <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?>
+                            subnet</option>
+                            <?php endfor; ?>
+                          </select></td>
+                      </tr>
+                      <tr> 
+                        <td>Address:&nbsp;&nbsp;</td>
+                        <td><input name="src" type="text" class="formfldalias" id="src" size="20" value="<?php if (!is_specialnet($pconfig['src'])) echo htmlspecialchars($pconfig['src']);?>">
+                          / 
+                          <select name="srcmask" class="formfld" id="srcmask">
+                            <?php for ($i = 31; $i > 0; $i--): ?>
+                            <option value="<?=$i;?>" <?php if ($i == $pconfig['srcmask']) echo "selected"; ?>> 
+                            <?=$i;?>
+                            </option>
+                            <?php endfor; ?>
+                          </select></td>
+                      </tr>
+                    </table></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Source port range 
+                  </td>
+                  <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>from:&nbsp;&nbsp;</td>
+                        <td><select name="srcbeginport" class="formfld" onchange="src_rep_change();ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['srcbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcbeginport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>> 
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="srcbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcbeginport']) echo $pconfig['srcbeginport']; ?>"></td>
+                      </tr>
+                      <tr> 
+                        <td>to:</td>
+                        <td><select name="srcendport" class="formfld" onchange="ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['srcendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['srcendport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>> 
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="srcendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['srcendport']) echo $pconfig['srcendport']; ?>"></td>
+                      </tr>
+                    </table>
+                    <br> <span class="vexpl">Specify the port or port range for 
+                    the source of the packet for this rule.<br>
+                    Hint: you can leave the <em>'to'</em> field empty if you only 
+                    want to filter a single port</span></td>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Destination</td>
+                  <td width="78%" class="vtable"> <input name="dstnot" type="checkbox" id="dstnot" value="yes" <?php if ($pconfig['dstnot']) echo "checked"; ?>> 
+                    <strong>not</strong><br>
+                    Use this option to invert the sense of the match.<br> <br> 
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>Type:&nbsp;&nbsp;</td>
+                        <td><select name="dsttype" class="formfld" onChange="typesel_change()">
+                            <?php $sel = is_specialnet($pconfig['dst']); ?>
+                            <option value="any" <?php if ($pconfig['dst'] == "any") { echo "selected"; } ?>> 
+                            any</option>
+                            <option value="single" <?php if (($pconfig['dstmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>> 
+                            Single host or alias</option>
+                            <option value="network" <?php if (!$sel) echo "selected"; ?>> 
+                            Network</option>
+                            <option value="lan" <?php if ($pconfig['dst'] == "lan") { echo "selected"; } ?>> 
+                            LAN subnet</option>
+                            <option value="pptp" <?php if ($pconfig['dst'] == "pptp") { echo "selected"; } ?>> 
+                            PPTP clients</option>
+                            <?php for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++): ?>
+                            <option value="opt<?=$i;?>" <?php if ($pconfig['dst'] == "opt" . $i) { echo "selected"; } ?>> 
+                            <?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?>
+                            subnet</option>
+                            <?php endfor; ?>
+                          </select> </td>
+                      </tr>
+                      <tr> 
+                        <td>Address:&nbsp;&nbsp;</td>
+                        <td><input name="dst" type="text" class="formfldalias" id="dst" size="20" value="<?php if (!is_specialnet($pconfig['dst'])) echo htmlspecialchars($pconfig['dst']);?>">
+                          / 
+                          <select name="dstmask" class="formfld" id="dstmask">
+                            <?php for ($i = 31; $i > 0; $i--): ?>
+                            <option value="<?=$i;?>" <?php if ($i == $pconfig['dstmask']) echo "selected"; ?>> 
+                            <?=$i;?>
+                            </option>
+                            <?php endfor; ?>
+                          </select></td>
+                      </tr>
+                    </table></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Destination port 
+                    range </td>
+                  <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>from:&nbsp;&nbsp;</td>
+                        <td><select name="dstbeginport" class="formfld" onchange="dst_rep_change();ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['dstbeginport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstbeginport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>> 
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="dstbeginport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstbeginport']) echo $pconfig['dstbeginport']; ?>"></td>
+                      </tr>
+                      <tr> 
+                        <td>to:</td>
+                        <td><select name="dstendport" class="formfld" onchange="ext_change()">
+                            <option value="">(other)</option>
+                            <option value="any" <?php $bfound = 0; if ($pconfig['dstendport'] == "any") { echo "selected"; $bfound = 1; } ?>>any</option>
+                            <?php foreach ($wkports as $wkport => $wkportdesc): ?>
+                            <option value="<?=$wkport;?>" <?php if ($wkport == $pconfig['dstendport']) {
+                                                                                                                               echo "selected";
+                                                                                                                               $bfound = 1;
+                                                                                                                       }?>> 
+                            <?=htmlspecialchars($wkportdesc);?>
+                            </option>
+                            <?php endforeach; ?>
+                          </select> <input name="dstendport_cust" type="text" size="5" value="<?php if (!$bfound && $pconfig['dstendport']) echo $pconfig['dstendport']; ?>"></td>
+                      </tr>
+                    </table>
+                    <br> <span class="vexpl">Specify the port or port range for 
+                    the destination of the packet for this rule.<br>
+                    Hint: you can leave the <em>'to'</em> field empty if you only 
+                    want to filter a single port</span></td>
+                <tr> 
+                  <td valign="top" class="vncell">Direction</td>
+                  <td class="vtable"> <select name="direction" class="formfld">
+                      <option value="" <?php if (!$pconfig['direction']) echo "selected"; ?>>any</option>
+                      <option value="in" <?php if ($pconfig['direction'] == "in") echo "selected"; ?>>in</option>
+                      <option value="out" <?php if ($pconfig['direction'] == "out") echo "selected"; ?>>out</option>
+                    </select> <br>
+                    Use this to match only packets travelling in a given direction 
+                    on the interface specified above (as seen from the firewall's 
+                    perspective). </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">IP packet length</td>
+                  <td width="78%" class="vtable"><input name="iplen" type="text" id="iplen" size="10" value="<?=htmlspecialchars($pconfig['iplen']);?>"> 
+                    <br>
+                    Setting this makes the rule match packets of a given length 
+                    (either a single value or a range in the syntax <em>from-to</em>, 
+                    e.g. 0-80). </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">TCP flags</td>
+                  <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+                      <?php 
+                                 $inflags = explode(",", $pconfig['tcpflags']);
+                                 foreach ($tcpflags as $tcpflag): $dontcare = true; ?>
+                      <tr> 
+                        <td width="40" nowrap><strong> 
+                          <?=strtoupper($tcpflag);?>
+                          </strong></td>
+                        <td nowrap> <input type="radio" name="tcpflags_<?=$tcpflag;?>" value="on" <?php if (array_search($tcpflag, $inflags) !== false) { echo "checked"; $dontcare = false; }?>>
+                          set&nbsp;&nbsp;&nbsp;</td>
+                        <td nowrap> <input type="radio" name="tcpflags_<?=$tcpflag;?>" value="off" <?php if (array_search("!" . $tcpflag, $inflags) !== false) { echo "checked"; $dontcare = false; }?>>
+                          cleared&nbsp;&nbsp;&nbsp;</td>
+                        <td nowrap> <input type="radio" name="tcpflags_<?=$tcpflag;?>" value="" <?php if ($dontcare) echo "checked";?>>
+                          don't care</td>
+                      </tr>
+                      <?php endforeach; ?>
+                    </table>
+                    <span class="vexpl">Use this to choose TCP flags that must 
+                    be set or cleared for this rule to match.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_shaper[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                                       <input name="after" type="hidden" value="<?=$after;?>">
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+ext_change();
+typesel_change();
+proto_change();
+//-->
+</script>
+<?php else: ?>
+<p><strong>You need to create a pipe or queue before you can add a new rule.</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_shaper_pipes.php b/webgui/firewall_shaper_pipes.php
new file mode 100644 (file)
index 0000000..e80500a
--- /dev/null
@@ -0,0 +1,165 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_shaper_pipes.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['shaper']['pipe'])) {
+       $config['shaper']['pipe'] = array();
+}
+if (!is_array($config['shaper']['queue'])) {
+       $config['shaper']['queue'] = array();
+}
+$a_pipes = &$config['shaper']['pipe'];
+
+if ($_GET['act'] == "del") {
+       if ($a_pipes[$_GET['id']]) {
+               /* check that no rule references this pipe */
+               if (is_array($config['shaper']['rule'])) {
+                       foreach ($config['shaper']['rule'] as $rule) {
+                               if (isset($rule['targetpipe']) && ($rule['targetpipe'] == $_GET['id'])) {
+                                       $input_errors[] = "This pipe cannot be deleted because it is still referenced by a rule.";
+                                       break;
+                               }
+                       }
+               }
+               
+               /* check that no queue references this pipe */
+               if (is_array($config['shaper']['queue'])) {
+                       foreach ($config['shaper']['queue'] as $queue) {
+                               if ($queue['targetpipe'] == $_GET['id']) {
+                                       $input_errors[] = "This pipe cannot be deleted because it is still referenced by a queue.";
+                                       break;
+                               }
+                       }
+               }
+               
+               if (!$input_errors) {
+                       unset($a_pipes[$_GET['id']]);
+                       
+                       /* renumber all rules and queues */
+                       if (is_array($config['shaper']['rule'])) {
+                               for ($i = 0; isset($config['shaper']['rule'][$i]); $i++) {
+                                       $currule = &$config['shaper']['rule'][$i];
+                                       if (isset($currule['targetpipe']) && ($currule['targetpipe'] > $_GET['id']))
+                                               $currule['targetpipe']--;
+                               }
+                       }
+                       if (is_array($config['shaper']['queue'])) {
+                               for ($i = 0; isset($config['shaper']['queue'][$i]); $i++) {
+                                       $curqueue = &$config['shaper']['queue'][$i];
+                                       if ($curqueue['targetpipe'] > $_GET['id'])
+                                               $curqueue['targetpipe']--;
+                               }
+                       }
+                       
+                       write_config();
+                       touch($d_shaperconfdirty_path);
+                       header("Location: firewall_shaper_pipes.php");
+                       exit;
+               }
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Traffic shaper</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper</p>
+<form action="firewall_shaper.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="firewall_shaper.php" class="tblnk">Rules</a></td>
+    <td nowrap class="tabact">Pipes</a></td>
+    <td nowrap class="tabinact"><a href="firewall_shaper_queues.php" class="tblnk">Queues</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="4" class="tabcont">
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                      <tr> 
+                        <td width="10%" class="listhdrr">No.</td>
+                        <td width="20%" class="listhdrr">Bandwidth</td>
+                        <td width="15%" class="listhdrr">Delay</td>
+                        <td width="15%" class="listhdrr">Mask</td>
+                        <td width="30%" class="listhdr">Description</td>
+                        <td width="10%" class="list"></td>
+                      </tr>
+                      <?php $i = 0; foreach ($a_pipes as $pipe): ?>
+                      <tr valign="top">
+                        <td class="listlr"> 
+                          <?=($i+1);?></td>
+                        <td class="listr"> 
+                          <?=htmlspecialchars($pipe['bandwidth']);?>
+                          Kbit/s </td>
+                        <td class="listr"> 
+                          <?php if ($pipe['delay']): ?>
+                          <?=$pipe['delay'];?>
+                          ms 
+                          <?php endif; ?>
+                          &nbsp; </td>
+                        <td class="listr"> 
+                          <?php if ($pipe['mask']): ?>
+                          <?=$pipe['mask'];?>
+                          <?php endif; ?>
+                          &nbsp; </td>
+                        <td class="listbg"> 
+                          <?=htmlspecialchars($pipe['descr']);?>
+                          &nbsp; </td>
+                        <td valign="middle" nowrap class="list"> <a href="firewall_shaper_pipes_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a> 
+                          &nbsp;<a href="firewall_shaper_pipes.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this pipe?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                      </tr>
+                      <?php $i++; endforeach; ?>
+                      <tr> 
+                        <td class="list" colspan="5"></td>
+                        <td class="list"> <a href="firewall_shaper_pipes_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                      </tr>
+                    </table>
+                               <p>
+                    <strong><span class="red">Note:</span></strong> a pipe can 
+                    only be deleted if it is not referenced by any rules or queues.</td></p>
+       </tr>
+</table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_shaper_pipes_edit.php b/webgui/firewall_shaper_pipes_edit.php
new file mode 100644 (file)
index 0000000..80650c7
--- /dev/null
@@ -0,0 +1,145 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_shaper_pipes_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$a_pipes = &$config['shaper']['pipe'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+       
+if (isset($id) && $a_pipes[$id]) {
+       $pconfig['bandwidth'] = $a_pipes[$id]['bandwidth'];
+       $pconfig['delay'] = $a_pipes[$id]['delay'];
+       $pconfig['mask'] = $a_pipes[$id]['mask'];
+       $pconfig['descr'] = $a_pipes[$id]['descr'];
+}
+
+if ($_POST) {
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "bandwidth");
+       $reqdfieldsn = explode(",", "Bandwidth");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['bandwidth'] && !is_numericint($_POST['bandwidth']))) {
+               $input_errors[] = "The bandwidth must be an integer.";
+       }
+       if (($_POST['delay'] && !is_numericint($_POST['delay']))) {
+               $input_errors[] = "The delay must be an integer.";
+       }
+
+       if (!$input_errors) {
+               $pipe = array();
+               
+               $pipe['bandwidth'] = $_POST['bandwidth'];
+               if ($_POST['delay'])
+                       $pipe['delay'] = $_POST['delay'];
+               if ($_POST['mask'])
+                       $pipe['mask'] = $_POST['mask'];
+               $pipe['descr'] = $_POST['descr'];
+               
+               if (isset($id) && $a_pipes[$id])
+                       $a_pipes[$id] = $pipe;
+               else
+                       $a_pipes[] = $pipe;
+               
+               write_config();
+               touch($d_shaperconfdirty_path);
+               
+               header("Location: firewall_shaper_pipes.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Traffic shaper: Edit pipe</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper: Edit pipe</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="firewall_shaper_pipes_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Bandwidth</td>
+                  <td width="78%" class="vtable"> <input name="bandwidth" type="text" id="bandwidth" size="5" value="<?=htmlspecialchars($pconfig['bandwidth']);?>"> 
+                    &nbsp;Kbit/s</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Delay</td>
+                  <td width="78%" class="vtable"> <input name="delay" type="text" id="delay" size="5" value="<?=htmlspecialchars($pconfig['delay']);?>"> 
+                    &nbsp;ms<br> <span class="vexpl">Hint: in most cases, you 
+                    should specify 0 here (or leave the field empty)</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Mask</td>
+                  <td width="78%" class="vtable"> <select name="mask" class="formfld">
+                      <option value="" <?php if (!$pconfig['mask']) echo "selected"; ?>>none</option>
+                      <option value="source" <?php if ($pconfig['mask'] == "source") echo "selected"; ?>>source</option>
+                      <option value="destination" <?php if ($pconfig['mask'] == "destination") echo "selected"; ?>>destination</option>
+                    </select> <br>
+                    <span class="vexpl">If 'source' or 'destination' is chosen, 
+                    a dynamic pipe with the bandwidth and delay given above will 
+                    be created for each source/destination IP address encountered, 
+                    respectively. This makes it possible to easily specify bandwidth 
+                    limits per host.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_pipes[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_shaper_queues.php b/webgui/firewall_shaper_queues.php
new file mode 100644 (file)
index 0000000..8a8bf76
--- /dev/null
@@ -0,0 +1,143 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_shaper_queues.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['shaper']['pipe'])) {
+       $config['shaper']['pipe'] = array();
+}
+if (!is_array($config['shaper']['queue'])) {
+       $config['shaper']['queue'] = array();
+}
+$a_queues = &$config['shaper']['queue'];
+
+if ($_GET['act'] == "del") {
+       if ($a_queues[$_GET['id']]) {
+               /* check that no rule references this queue */
+               if (is_array($config['shaper']['rule'])) {
+                       foreach ($config['shaper']['rule'] as $rule) {
+                               if (isset($rule['targetqueue']) && ($rule['targetqueue'] == $_GET['id'])) {
+                                       $input_errors[] = "This queue cannot be deleted because it is still referenced by a rule.";
+                                       break;
+                               }
+                       }
+               }
+               
+               if (!$input_errors) {
+                       unset($a_queues[$_GET['id']]);
+                       
+                       /* renumber all rules */
+                       if (is_array($config['shaper']['rule'])) {
+                               for ($i = 0; isset($config['shaper']['rule'][$i]); $i++) {
+                                       $currule = &$config['shaper']['rule'][$i];
+                                       if (isset($currule['targetqueue']) && ($currule['targetqueue'] > $_GET['id']))
+                                               $currule['targetqueue']--;
+                               }
+                       }
+                       
+                       write_config();
+                       touch($d_shaperconfdirty_path);
+                       header("Location: firewall_shaper_queues.php");
+                       exit;
+               }
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Traffic shaper</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper</p>
+<form action="firewall_shaper.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_shaperconfdirty_path)): ?><p>
+<?php print_info_box_np("The traffic shaper configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="firewall_shaper.php" class="tblnk">Rules</a></td>
+    <td nowrap class="tabinact"><a href="firewall_shaper_pipes.php" class="tblnk">Pipes</a></a></td>
+    <td nowrap class="tabact">Queues</td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="4" class="tabcont">
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                      <tr> 
+                        <td width="10%" class="listhdrr">No.</td>
+                        <td width="15%" class="listhdrr">Pipe</td>
+                        <td width="15%" class="listhdrr">Weight</td>
+                        <td width="20%" class="listhdrr">Mask</td>
+                        <td width="30%" class="listhdr">Description</td>
+                        <td width="10%" class="list"></td>
+                      </tr>
+                      <?php $i = 0; foreach ($a_queues as $queue): ?>
+                      <tr valign="top"> 
+                        <td class="listlr"> 
+                          <?=($i+1);?></td>
+                        <td class="listr"> 
+                          <a href="firewall_shaper_pipes_edit.php?id=<?=$queue['targetpipe'];?>"><?=$queue['targetpipe']+1;?></a></td>
+                        <td class="listr"> 
+                          <?=$queue['weight'];?></td>
+                        <td class="listr"> 
+                          <?php if ($queue['mask']): ?>
+                          <?=$queue['mask'];?>
+                          <?php endif; ?>
+                          &nbsp; </td>
+                        <td class="listbg"> 
+                          <?=htmlspecialchars($queue['descr']);?>
+                          &nbsp; </td>
+                        <td valign="middle" nowrap class="list"> <a href="firewall_shaper_queues_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a> 
+                          &nbsp;<a href="firewall_shaper_queues.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this queue?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                      </tr>
+                      <?php $i++; endforeach; ?>
+                      <tr> 
+                        <td class="list" colspan="5"></td>
+                        <td class="list"> <a href="firewall_shaper_queues_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                      </tr>
+                    </table>
+                               <p>
+                    <strong><span class="red">Note:</span></strong> a queue can 
+                    only be deleted if it is not referenced by any rules.</td></p>
+       </tr>
+</table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/firewall_shaper_queues_edit.php b/webgui/firewall_shaper_queues_edit.php
new file mode 100644 (file)
index 0000000..48e4ef7
--- /dev/null
@@ -0,0 +1,162 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       firewall_shaper_queues_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$a_queues = &$config['shaper']['queue'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_queues[$id]) {
+       $pconfig['targetpipe'] = $a_queues[$id]['targetpipe'];
+       $pconfig['weight'] = $a_queues[$id]['weight'];
+       $pconfig['mask'] = $a_queues[$id]['mask'];
+       $pconfig['descr'] = $a_queues[$id]['descr'];
+}
+
+if ($_POST) {
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "weight");
+       $reqdfieldsn = explode(",", "Weight");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if ($_POST['weight'] && (!is_numericint($_POST['weight'])
+                       || ($_POST['weight'] < 1) || ($_POST['weight'] > 100))) {
+               $input_errors[] = "The weight must be an integer between 1 and 100.";
+       }
+
+       if (!$input_errors) {
+               $queue = array();
+               
+               $queue['targetpipe'] = $_POST['targetpipe'];
+               $queue['weight'] = $_POST['weight'];
+               if ($_POST['mask'])
+                       $queue['mask'] = $_POST['mask'];
+               $queue['descr'] = $_POST['descr'];
+               
+               if (isset($id) && $a_queues[$id])
+                       $a_queues[$id] = $queue;
+               else
+                       $a_queues[] = $queue;
+               
+               write_config();
+               touch($d_shaperconfdirty_path);
+               
+               header("Location: firewall_shaper_queues.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Firewall: Traffic shaper: Edit queue</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Firewall: Traffic shaper: Edit queue</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+<?php if (is_array($config['shaper']['pipe']) && (count($config['shaper']['pipe']) > 0)): ?>
+            <form action="firewall_shaper_queues_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td valign="top" class="vncellreq">Pipe</td>
+                  <td class="vtable"> <select name="targetpipe" class="formfld">
+                      <?php 
+                                         foreach ($config['shaper']['pipe'] as $pipei => $pipe): ?>
+                      <option value="<?=$pipei;?>" <?php if ($pipei == $pconfig['targetpipe']) echo "selected"; ?>> 
+                      <?php
+                                               echo htmlspecialchars("Pipe " . ($pipei + 1));
+                                               if ($pipe['descr'])
+                                                       echo htmlspecialchars(" (" . $pipe['descr'] . ")");
+                                         ?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Choose the pipe that this queue is linked 
+                    to.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Weight</td>
+                  <td width="78%" class="vtable"> <input name="weight" type="text" id="weight" size="5" value="<?=htmlspecialchars($pconfig['weight']);?>"> 
+                    <br> <span class="vexpl">Valid range: 1..100.<br>
+                    All backlogged (i.e., with packets queued) queues linked to 
+                    the same pipe share the pipe's bandwidth proportionally to 
+                    their weights (higher weight = higher share of bandwidth). 
+                    Note that weights are not priorities; a queue with a lower 
+                    weight is still guaranteed to get its fraction of the bandwidth 
+                    even if a queue with a higher weight is permanently backlogged.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Mask</td>
+                  <td width="78%" class="vtable"> <select name="mask" class="formfld">
+                      <option value="" <?php if (!$pconfig['mask']) echo "selected"; ?>>none</option>
+                      <option value="source" <?php if ($pconfig['mask'] == "source") echo "selected"; ?>>source</option>
+                      <option value="destination" <?php if ($pconfig['mask'] == "destination") echo "selected"; ?>>destination</option>
+                    </select> <br> <span class="vexpl">If 'source' or 'destination' 
+                    is chosen, a dynamic queue associated with the pipe and with 
+                    the weight given above will be created for each source/destination 
+                    IP address encountered, respectively. This makes it possible 
+                    to easily specify bandwidth limits per host.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_queues[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php else: ?>
+<p><strong>You need to create a pipe before you can add a new queue.</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/gui.css b/webgui/gui.css
new file mode 100644 (file)
index 0000000..b019c31
--- /dev/null
@@ -0,0 +1,259 @@
+body,td,th,input,select {
+       font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+       font-size: 11px;
+}
+form {
+       margin: 0px;
+}
+.pgtitle {
+       font-size: 18px;
+       color: #777777;
+       font-weight: bold;
+}
+.tfrtitle {
+       font-size: 18px;
+       color: #ffffff;
+       font-weight: bold;
+}
+.vncell {
+       background-color: #DDDDDD;
+       padding-right: 20px;
+       padding-left: 8px;
+       border-bottom: 1px solid #999999;
+}
+.formfld {
+
+}
+.formfldalias {
+       background-color: #e7edf9;
+}
+.formpre {
+       font-family: Courier New, Courier, monospaced;
+       font-size: 10px;
+}
+.formbtn {
+       font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif;
+       font-size: 13px;
+       font-weight: bold;
+}
+.vvcell {
+       background-color: #FFFFC6;
+}
+.errmsg {
+       font-weight: bold;
+       color: #CC0000;
+}
+.red {
+       color: #CC0000;
+}
+.gray {
+       color: #A0A0A0;
+}
+.vexpl {
+       font-size: 11px;
+}
+a {
+       text-decoration: none;
+}
+.navlnk {
+       color: #FFFFFF;
+       text-decoration: none;
+       font-size: 13px;
+}
+.navlnks {
+       color: #FFFFFF;
+       text-decoration: none;
+       font-size: 11px;
+}
+.tblnk {
+       color: #FFFFFF;
+       text-decoration: none;
+}
+.vncellreq {
+       background-color: #DDDDDD;
+       padding-right: 20px;
+       padding-left: 8px;
+       font-weight: bold;
+       border-bottom: 1px solid #999999;
+}
+.vncellt {
+       background-color: #DDDDDD;
+       padding-right: 20px;
+       padding-left: 8px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+       font-weight: bold;
+       border-bottom: 1px solid #999999;
+}
+.vtable {
+       border-bottom: 1px solid #999999;
+}
+.vnsepcell {
+       background-color: #BBBBBB;
+       padding-right: 20px;
+       padding-left: 8px;
+       font-weight: bold;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+}
+.cpline {
+       font-size: 11px;
+       color: #FFFFFF;
+}
+.vnsepcellr {
+       background-color: #BBBBBB;
+       padding-right: 20px;
+       padding-left: 8px;
+       font-weight: bold;
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+}
+.listr {
+       background-color: #FFFFFF;
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+       padding-right: 16px;
+       padding-left: 6px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+.listrpad {
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+       padding-right: 16px;
+       padding-left: 10px;
+       padding-top: 8px;
+       padding-bottom: 8px;
+}
+.listn {
+       font-size: 11px;
+       padding-right: 16px;
+       padding-left: 6px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+.listbg {
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+       background-color: #D9DEE8;
+       padding-right: 16px;
+       padding-left: 6px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+.listhdr {
+       background-color: #BBBBBB;
+       padding-right: 16px;
+       padding-left: 6px;
+       font-weight: bold;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+       padding-top: 5px;
+       padding-bottom: 5px;
+}
+.listhdrr {
+       background-color: #BBBBBB;
+       padding-right: 16px;
+       padding-left: 6px;
+       font-weight: bold;
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+       padding-top: 5px;
+       padding-bottom: 5px;
+}
+.listlr {
+       background-color: #FFFFFF;
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       border-left: 1px solid #999999;
+       font-size: 11px;
+       padding-right: 16px;
+       padding-left: 6px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+.listlrns {
+       background-color: #FFFFFF;
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       border-left: 1px solid #999999;
+       font-size: 11px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+.list {
+       font-size: 11px;
+       padding-left: 6px;
+       padding-top: 2px;
+       padding-bottom: 2px;
+}
+.listt {
+       font-size: 11px;
+       padding-top: 5px;
+       padding-left: 4px;
+}
+.listhdrrns {
+       background-color: #BBBBBB;
+       padding-left: 6px;
+       padding-top: 5px;
+       padding-bottom: 5px;
+       padding-right: 6px;
+       font-weight: bold;
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+}
+.listbgns {
+       border-right: 1px solid #999999;
+       border-bottom: 1px solid #999999;
+       font-size: 11px;
+       background-color: #D9DEE8;
+       padding-left: 6px;
+       padding-right: 4px;
+       padding-top: 4px;
+       padding-bottom: 4px;
+}
+.listtopic {
+       border-right: 1px solid #999999;
+       font-size: 11px;
+       background-color: #435370;
+       padding-right: 16px;
+       padding-left: 6px;
+       color: #FFFFFF;
+       font-weight: bold;
+       padding-top: 5px;
+       padding-bottom: 5px;
+}
+.tabinact {
+       border-left: 1px solid #999999;
+       font-size: 11px;
+       background-color: #777777;
+       padding-right: 8px;
+       padding-left: 8px;
+       padding-top: 5px;
+       padding-bottom: 5px;
+       color: #FFFFFF;
+       font-weight: bold;
+}
+.tabact {
+       font-size: 11px;
+       background-color: #EEEEEE;
+       padding-right: 8px;
+       padding-left: 8px;
+       padding-top: 5px;
+       padding-bottom: 5px;
+       color: #000000;
+       font-weight: bold;
+}
+.tabcont {
+       background-color: #EEEEEE;
+       padding-right: 12px;
+       padding-left: 12px;
+       padding-top: 12px;
+       padding-bottom: 12px;
+}
diff --git a/webgui/guiconfig.inc b/webgui/guiconfig.inc
new file mode 100644 (file)
index 0000000..8cd038a
--- /dev/null
@@ -0,0 +1,398 @@
+<?php
+/*
+       guiconfig.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+/* make sure nothing is cached */
+if (!$omit_nocacheheaders) {
+       header("Expires: 0");
+       header("Last-Modified: " . gmdate("D, d M Y H:i:s") . " GMT");
+       header("Cache-Control: no-store, no-cache, must-revalidate");
+       header("Cache-Control: post-check=0, pre-check=0", false);
+       header("Pragma: no-cache");
+}
+
+$d_natconfdirty_path = $g['varrun_path'] . "/nat.conf.dirty";
+$d_filterconfdirty_path = $g['varrun_path'] . "/filter.conf.dirty";
+$d_ipsecconfdirty_path = $g['varrun_path'] . "/ipsec.conf.dirty";
+$d_shaperconfdirty_path = $g['varrun_path'] . "/shaper.conf.dirty";
+$d_pptpuserdirty_path = $g['varrun_path'] . "/pptpd.user.dirty";
+$d_hostsdirty_path = $g['varrun_path'] . "/hosts.dirty";
+$d_staticmapsdirty_path = $g['varrun_path'] . "/staticmaps.dirty";
+$d_staticroutesdirty_path = $g['varrun_path'] . "/staticroutes.dirty";
+$d_aliasesdirty_path = $g['varrun_path'] . "/aliases.dirty";
+$d_proxyarpdirty_path = $g['varrun_path'] . "/proxyarp.dirty";
+$d_fwupenabled_path = $g['varrun_path'] . "/fwup.enabled";
+$d_firmwarelock_path = $g['varrun_path'] . "/firmware.lock";
+$d_sysrebootreqd_path = $g['varrun_path'] . "/sysreboot.reqd";
+
+if (file_exists($d_firmwarelock_path)) {
+       if (!$d_isfwfile) {
+               header("Location: system_firmware.php");
+               exit;
+       } else {
+               return;
+       }
+}
+
+/* parse the configuration and include all configuration functions */
+require_once("config.inc");
+require_once("functions.inc");
+
+/* some well knows ports */
+$wkports = array(21 => "FTP", 22 => "SSH", 23 => "Telnet", 25 => "SMTP", 53 => "DNS", 80 => "HTTP",
+                                110 => "POP3", 143 => "IMAP", 443 => "HTTPS");
+
+/* TCP flags */
+$tcpflags = array("fin", "syn", "rst", "psh", "ack", "urg");
+
+$specialnets = array("lan" => "LAN net", "pptp" => "PPTP clients");
+
+for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+       $specialnets['opt' . $i] = $config['interfaces']['opt' . $i]['descr'] . " net";
+}
+       
+$medias = array("auto" => "autoselect", "100full" => "100BASE-TX full-duplex",
+       "100half" => "100BASE-TX half-duplex", "10full" => "10BASE-T full-duplex",
+       "10half" => "10BASE-T half-duplex");
+       
+/* platforms that support firmware updating */
+$fwupplatforms = array('net45xx', 'net48xx', 'generic-pc', 'wrap');
+
+/* IPsec defines */
+$my_identifier_list = array('myaddress' => 'My IP address',
+                                                       'address' => 'IP address',
+                                                       'fqdn' => 'Domain name');
+
+$p1_ealgos = array('des' => 'DES', '3des' => '3DES', 'blowfish' => 'Blowfish', 
+                                       'cast128' => 'CAST128');
+$p2_ealgos = array('des' => 'DES', '3des' => '3DES', 'blowfish' => 'Blowfish',
+                                       'cast128' => 'CAST128', 'rijndael' => 'Rijndael (AES)');
+$p1_halgos = array('md5' => 'MD5', 'sha1' => 'SHA1');
+$p2_halgos = array('hmac_md5' => 'MD5', 'hmac_sha1' => 'SHA1');
+$p2_protos = array('esp' => 'ESP', 'ah' => 'AH');
+$p2_pfskeygroups = array('0' => 'off', '1' => '1', '2' => '2', '5' => '5');
+
+function do_input_validation($postdata, $reqdfields, $reqdfieldsn, $input_errors) {
+       for ($i = 0; $i < count($reqdfields); $i++) {
+               if (!$_POST[$reqdfields[$i]]) {
+                       $input_errors[] = "The field '" . $reqdfieldsn[$i] . "' is required.";
+               }
+       }       
+}
+
+function print_input_errors($input_errors) {
+       echo "<p><table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100%\">\n";
+       echo "<tr><td bgcolor=\"#A12A2A\" width=\"36\" align=\"center\" valign=\"top\"><img src=\"err.gif\" width=\"28\" height=\"32\"></td>\n";
+       echo "<td bgcolor=\"#FFD9D1\" style=\"padding-left: 8px; padding-top: 6px\">";
+       
+       echo "<span class=\"errmsg\"><p>The following input errors were detected:<ul>\n";
+       foreach ($input_errors as $ierr) {
+               echo "<li>" . htmlspecialchars($ierr) . "</li>\n";
+       }
+       echo "</ul></span>";
+       
+       echo "</td></tr></table></p>";
+}
+
+function exec_rc_script($scriptname) {
+       
+       global $d_sysrebootreqd_path;
+       
+       if (file_exists($d_sysrebootreqd_path))
+               return 0;
+       
+       exec($scriptname . " >/dev/null 2>&1", $execoutput, $retval);
+       return $retval; 
+}
+
+function exec_rc_script_async($scriptname) {
+       
+       global $d_sysrebootreqd_path;
+       
+       if (file_exists($d_sysrebootreqd_path))
+               return 0;
+               
+       exec("nohup " . $scriptname . " >/dev/null 2>&1 &", $execoutput, $retval);
+       return $retval; 
+}
+
+function verify_gzip_file($fname) {
+
+       $returnvar = mwexec("/usr/bin/gunzip -S \"\" -t " . escapeshellarg($fname));
+       if ($returnvar != 0)
+               return 0;
+       else
+               return 1;
+}
+
+function print_info_box_np($msg) {
+       echo "<table border=\"0\" cellspacing=\"0\" cellpadding=\"4\" width=\"100%\">\n";
+       echo "<tr><td bgcolor=\"#687BA4\" align=\"center\" valign=\"top\" width=\"36\"><img src=\"exclam.gif\" width=\"28\" height=\"32\"></td>\n";
+       echo "<td bgcolor=\"#D9DEE8\" style=\"padding-left: 8px\">";
+       echo $msg;
+       echo "</td></tr></table>";
+}
+
+function print_info_box($msg) {
+       echo "<p>";
+       print_info_box_np($msg);
+       echo "</p>";
+}
+
+function format_bytes($bytes) {
+       if ($bytes >= 1073741824) {
+               return sprintf("%.2f GB", $bytes/1073741824);
+       } else if ($bytes >= 1048576) {
+               return sprintf("%.2f MB", $bytes/1048576);
+       } else if ($bytes >= 1024) {
+               return sprintf("%.0f KB", $bytes/1024);
+       } else {
+               return sprintf("%d bytes", $bytes);
+       }
+}
+
+function get_std_save_message($ok) {
+       global $d_sysrebootreqd_path;
+
+       if ($ok == 0) {
+               if (file_exists($d_sysrebootreqd_path))
+                       return "The changes have been saved. You must reboot your firewall for changes to take effect.";
+               else
+                       return "The changes have been applied successfully.";
+       } else {
+               return "ERROR: the changes could not be applied (error code $ok).";
+       }
+}
+
+function pprint_address($adr) {
+       global $specialnets;
+
+       if (isset($adr['any'])) {
+               $padr = "*";
+       } else if ($adr['network']) {
+               $padr = $specialnets[$adr['network']];
+       } else {
+               $padr = $adr['address'];
+       }
+       
+       if (isset($adr['not']))
+               $padr = "! " . $padr;
+       
+       return $padr;
+}
+
+function pprint_port($port) {
+       global $wkports;
+
+       $pport = "";
+               
+       if (!$port)
+               echo "*";
+       else {
+               $srcport = explode("-", $port);
+               if ((!$srcport[1]) || ($srcport[0] == $srcport[1])) {
+                       $pport = $srcport[0];
+                       if ($wkports[$srcport[0]]) {
+                               $pport .= " (" . $wkports[$srcport[0]] . ")";
+                       }
+               } else
+                       $pport .= $srcport[0] . " - " . $srcport[1];
+       }
+       
+       return $pport;
+}
+
+/* sort by interface only, retain the original order of rules that apply to
+   the same interface */
+function filter_rules_sort() {
+       global $g, $config;
+       
+       /* mark each rule with the sequence number (to retain the order while sorting) */
+       for ($i = 0; isset($config['filter']['rule'][$i]); $i++)
+               $config['filter']['rule'][$i]['seq'] = $i;
+       
+       function filtercmp($a, $b) {
+               if ($a['interface'] == $b['interface'])
+                       return $a['seq'] - $b['seq'];
+               else
+                       return -strcmp($a['interface'], $b['interface']);
+       }
+       
+       usort($config['filter']['rule'], "filtercmp");
+       
+       /* strip the sequence numbers again */
+       for ($i = 0; isset($config['filter']['rule'][$i]); $i++)
+               unset($config['filter']['rule'][$i]['seq']);
+}
+
+function nat_rules_sort() {
+       global $g, $config;
+       
+       function natcmp($a, $b) {
+               if ($a['external-address'] == $b['external-address']) {
+                       if ($a['protocol'] == $b['protocol']) {
+                               if ($a['external-port'] == $b['external-port']) {
+                                       return 0;
+                               } else {
+                                       return ($a['external-port'] - $b['external-port']);
+                               }
+                       } else {
+                               return strcmp($a['protocol'], $b['protocol']);
+                       }
+               } else if (!$a['external-address'])
+                       return 1;
+               else if (!$b['external-address'])
+                       return -1;
+               else
+                       return ipcmp($a['external-address'], $b['external-address']);
+       }
+       
+       usort($config['nat']['rule'], "natcmp");
+}
+
+function nat_1to1_rules_sort() {
+       global $g, $config;
+       
+       function nat1to1cmp($a, $b) {
+               return ipcmp($a['external'], $b['external']);
+       }
+       
+       usort($config['nat']['onetoone'], "nat1to1cmp");
+}
+
+function nat_server_rules_sort() {
+       global $g, $config;
+       
+       function natservercmp($a, $b) {
+               return ipcmp($a['ipaddr'], $b['ipaddr']);
+       }
+       
+       usort($config['nat']['servernat'], "natservercmp");
+}
+
+function nat_out_rules_sort() {
+       global $g, $config;
+       
+       function natoutcmp($a, $b) {
+               return strcmp($a['source']['network'], $b['source']['network']);
+       }
+       
+       usort($config['nat']['advancedoutbound']['rule'], "natoutcmp");
+}
+
+function pptpd_users_sort() {
+       global $g, $config;
+       
+       function usercmp($a, $b) {
+               return strcasecmp($a['name'], $b['name']);
+       }
+       
+       usort($config['pptpd']['user'], "usercmp");
+}
+
+function staticroutes_sort() {
+       global $g, $config;
+
+       function staticroutecmp($a, $b) {
+               return strcmp($a['network'], $b['network']);
+       }
+
+       usort($config['staticroutes']['route'], "staticroutecmp");
+}
+
+function hosts_sort() {
+       global $g, $config;
+
+       function hostcmp($a, $b) {
+               return strcasecmp($a['host'], $b['host']);
+       }
+
+       usort($config['dnsmasq']['hosts'], "hostcmp");
+}
+
+function staticmaps_sort($if) {
+       global $g, $config;
+
+       function staticmapcmp($a, $b) {
+               return ipcmp($a['ipaddr'], $b['ipaddr']);
+       }
+
+       usort($config['dhcpd'][$if]['staticmap'], "staticmapcmp");
+}
+
+function aliases_sort() {
+       global $g, $config;
+
+       function aliascmp($a, $b) {
+               return strcmp($a['name'], $b['name']);
+       }
+
+       usort($config['aliases']['alias'], "aliascmp");
+}
+
+function ipsec_mobilekey_sort() {
+       global $g, $config;
+
+       function mobilekeycmp($a, $b) {
+               return strcmp($a['ident'][0], $b['ident'][0]);
+       }
+
+       usort($config['ipsec']['mobilekey'], "mobilekeycmp");
+}
+
+function proxyarp_sort() {
+       global $g, $config;
+
+       function proxyarpcmp($a, $b) {
+               if (isset($a['network']))
+                       list($ast,$asn) = explode("/", $a['network']);
+               else if (isset($a['range'])) {
+                       $ast = $a['range']['from'];
+                       $asn = 32;
+               }
+               if (isset($b['network']))
+                       list($bst,$bsn) = explode("/", $b['network']);
+               else if (isset($b['range'])) {
+                       $bst = $b['range']['from'];
+                       $bsn = 32;
+               }
+               if (ipcmp($ast, $bst) == 0)
+                       return ($asn - $bsn);
+               else
+                       return ipcmp($ast, $bst);
+       }
+
+       usort($config['proxyarp']['proxyarpnet'], "proxyarpcmp");
+}
+
+function is_numericint($arg) {
+       return (preg_match("/[^0-9]/", $arg) ? false : true);
+}
+
+?>
diff --git a/webgui/in.gif b/webgui/in.gif
new file mode 100644 (file)
index 0000000..95a67cf
Binary files /dev/null and b/webgui/in.gif differ
diff --git a/webgui/index.php b/webgui/index.php
new file mode 100644 (file)
index 0000000..e3a2908
--- /dev/null
@@ -0,0 +1,104 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       index.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+/* find out whether there's hardware encryption (hifn) */
+exec("/sbin/dmesg", $dmesg);
+
+unset($hwcrypto);
+foreach ($dmesg as $dmesgl) {
+       if (preg_match("/^hifn.: (.*?),/", $dmesgl, $matches)) {
+               $hwcrypto = $matches[1];
+               break;
+       }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+            <table width="100%" border="0" cellspacing="0" cellpadding="0">
+              <tr align="center" valign="top"> 
+                <td height="10" colspan="2">&nbsp;</td>
+              </tr>
+              <tr align="center" valign="top"> 
+                <td height="170" colspan="2"><img src="logobig.gif" width="520" height="149"></td>
+              </tr>
+              <tr> 
+                <td colspan="2" class="listtopic">System information</td>
+              </tr>
+              <tr> 
+                <td width="25%" class="vncellt">Name</td>
+                <td width="75%" class="listr">
+                  <?php echo $config['system']['hostname'] . "." . $config['system']['domain']; ?>
+                </td>
+              </tr>
+              <tr> 
+                <td width="25%" valign="top" class="vncellt">Version</td>
+                <td width="75%" class="listr"> <strong> 
+                  <?php readfile("/etc/version"); ?>
+                  </strong><br>
+                  built on 
+                  <?php readfile("/etc/version.buildtime"); ?>
+                </td>
+              </tr>
+              <tr> 
+                <td width="25%" class="vncellt">Platform</td>
+                <td width="75%" class="listr"> 
+                  <?=htmlspecialchars($g['platform']);?>
+                </td>
+              </tr><?php if ($hwcrypto): ?>
+              <tr> 
+                <td width="25%" class="vncellt">Hardware crypto</td>
+                <td width="75%" class="listr"> 
+                  <?=htmlspecialchars($hwcrypto);?>
+                </td>
+              </tr><?php endif; ?>
+              <tr> 
+                <td width="25%" class="vncellt">Uptime</td>
+                <td width="75%" class="listr"> 
+                  <?php exec("/usr/bin/uptime", $uptime);
+                                       $uptimea = explode(",", $uptime[0], 3);
+                                       echo join(",", array($uptimea[0], $uptimea[2])); ?>
+                </td>
+              </tr>
+            </table>
+            <?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/interfaces_assign.php b/webgui/interfaces_assign.php
new file mode 100644 (file)
index 0000000..e992d96
--- /dev/null
@@ -0,0 +1,249 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       interfaces_assign.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       Written by Jim McBeath based on existing m0n0wall files
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+/*
+       In this file, "port" refers to the physical port name,
+       while "interface" refers to LAN, WAN, or OPTn.
+*/
+
+$portlist = get_interface_list();
+
+if ($_POST) {
+
+       unset($input_errors);
+
+       /* input validation */
+
+       /* Build a list of the port names so we can see how the interfaces map */
+       $portifmap = array();
+       foreach ($portlist as $portname => $portinfo)
+               $portifmap[] = array($portname => array());
+
+       /* Go through the list of ports selected by the user,
+          build a list of port-to-interface mappings in portifmap */
+       foreach ($_POST as $ifname => $ifport) {
+               if (($ifname == 'lan') || ($ifname == 'wan') || (substr($ifname, 0, 3) == 'opt'))
+                       $portifmap[$ifport][] = strtoupper($ifname);
+       }
+
+       /* Deliver error message for any port with more than one assignment */
+       foreach ($portifmap as $portname => $ifnames) {
+               if (count($ifnames) > 1) {
+                       $errstr = "Port " . $portname .
+                               " was assigned to " . count($ifnames) .
+                               " interfaces:";
+                               
+                       foreach ($portifmap[$portname] as $ifn)
+                               $errstr .= "  " . $ifn;
+                       
+                       $input_errors[] = $errstr;
+               }
+       }
+
+
+       if (!$input_errors) {
+               /* No errors detected, so update the config */
+               foreach ($_POST as $ifname => $ifport) {
+               
+                       if (($ifname == 'lan') || ($ifname == 'wan') ||
+                               (substr($ifname, 0, 3) == 'opt')) {
+                               
+                               if (!is_array($ifport)) {
+                                       $config['interfaces'][$ifname]['if'] = $ifport;
+                                       
+                                       /* check for wireless interfaces, set or clear ['wireless'] */
+                                       if (preg_match("/^(wi|awi|an)/", $ifport)) {
+                                               if (!is_array($config['interfaces'][$ifname]['wireless']))
+                                                       $config['interfaces'][$ifname]['wireless'] = array();
+                                       } else {
+                                               unset($config['interfaces'][$ifname]['wireless']);
+                                       }
+                                       
+                                       /* make sure there is a name for OPTn */
+                                       if (substr($ifname, 0, 3) == 'opt') {
+                                               if (!isset($config['interfaces'][$ifname]['descr']))
+                                                       $config['interfaces'][$ifname]['descr'] = strtoupper($ifname);
+                                       }
+                               }
+                       }
+               }
+       
+               write_config();
+               touch($d_sysrebootreqd_path);
+               /* message is set up below based on existence of bootreqd file */
+       }
+}
+
+if ($_GET['act'] == "del") {
+       $id = $_GET['id'];
+       
+       unset($config['interfaces'][$id]);      /* delete the specified OPTn */
+
+       /* shift down other OPTn interfaces to get rid of holes */
+       $i = substr($id, 3); /* the number of the OPTn port being deleted */
+       $i++;
+       
+       /* look at the following OPTn ports */
+       while (is_array($config['interfaces']['opt' . $i])) {
+               $config['interfaces']['opt' . ($i - 1)] =
+                       $config['interfaces']['opt' . $i];
+               
+               if ($config['interfaces']['opt' . ($i - 1)]['descr'] == "OPT" . $i)
+                       $config['interfaces']['opt' . ($i - 1)]['descr'] = "OPT" . ($i - 1);
+               
+               unset($config['interfaces']['opt' . $i]);
+               $i++;
+       }
+
+       write_config();
+       touch($d_sysrebootreqd_path);
+       header("Location: interfaces_assign.php");
+       exit;
+}
+
+if ($_GET['act'] == "add") {
+       $i = 0;
+       
+       while (1) {
+               $newifname = 'opt' . ($i+1);
+               
+               if (!is_array($config['interfaces'][$newifname])) {
+                       $config['interfaces'][$newifname] = array();
+                       $config['interfaces'][$newifname]['descr'] = "OPT" . ($i+1);
+                       
+                       /* Find an unused port for this interface */
+                       foreach ($portlist as $portname => $portinfo) {
+                               $portused = false;
+                               foreach ($config['interfaces'] as $ifname => $ifdata) {
+                                       if ($ifdata['if'] == $portname) {
+                                               $portused = true;
+                                               break;
+                                       }
+                               }
+                               if (!$portused) {
+                                       $config['interfaces'][$newifname]['if'] = $portname;
+                                       if (preg_match("/^(wi|awi|an)/", $portname))
+                                               $config['interfaces'][$newifname]['wireless'] = array();
+                                       break;
+                               }
+                       }
+                       break;
+               }
+               $i++;
+       }
+       
+       write_config();
+       touch($d_sysrebootreqd_path);
+       header("Location: interfaces_assign.php");
+       exit;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Interfaces: Assign network ports</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: Assign network ports</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="interfaces_assign.php" method="post" name="iform" id="iform">
+              <table border="0" cellpadding="6" cellspacing="0">
+                <tr>
+  <td width="22%" valign="top" class="vncellreq">Interface assignments</td>
+                  <td width="78%" class="vtable"> 
+                    <table border="0" cellpadding="0" cellspacing="0">
+                      <tr> 
+       <td class="listhdrr">Interface</td>
+       <td class="listhdrr">Network port</td>
+       <td class="list">&nbsp;</td>
+  </tr>
+  <?php foreach ($config['interfaces'] as $ifname => $iface): ?>
+  <tr> 
+       <td class="listlr" valign="middle"><strong><?=strtoupper($ifname);?></strong></td>
+         <td valign="middle" class="listr">
+               <select name="<?=$ifname;?>" class="formfld" id="<?=$ifname;?>">
+                 <?php foreach ($portlist as $portname => $portinfo): ?>
+                 <option value="<?=$portname;?>" <?php if ($portname == $iface['if']) echo "selected";?>> 
+                 <?=htmlspecialchars($portname . " (" . $portinfo['mac'] . ")");?>
+                 </option>
+                 <?php endforeach; ?>
+               </select>
+               </td>
+               <td valign="middle" class="list"> 
+                 <?php if (($ifname != 'lan') && ($ifname != 'wan')): ?>
+                 <a href="interfaces_assign.php?act=del&id=<?=$ifname;?>"><img src="x.gif" alt="delete interface" width="17" height="17" border="0"></a> 
+                 <?php endif; ?>
+               </td>
+  </tr>
+  <?php endforeach; ?>
+  <tr>
+       <td class="list" colspan="2"></td>
+       <td class="list" nowrap><?php if (count($config['interfaces']) < count($portlist)): ?> 
+       <a href="interfaces_assign.php?act=add"><img src="plus.gif" alt="add interface" width="17" height="17" border="0"></a>
+       <?php endif; ?> </td>
+  </tr>
+</table>
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                      <input name="Submit" type="submit" class="formbtn" value="Save">
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> <span class="vexpl"><span class="red"><strong>Warning:<br>
+                    </strong></span>After you click &quot;Save&quot;, you must 
+                    reboot the firewall to make the changes take effect. You may 
+                    also have to do one or more of the following steps before 
+                    you can access your firewall again: 
+                    <ul>
+                      <li>change the IP address of your computer</li>
+                      <li>renew it's DHCP lease</li>
+                      <li>access the webGUI with the new IP address</li>
+                    </ul>
+                    </span></td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/interfaces_lan.php b/webgui/interfaces_lan.php
new file mode 100644 (file)
index 0000000..72101fe
--- /dev/null
@@ -0,0 +1,173 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       interfaces_lan.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$lancfg = &$config['interfaces']['lan'];
+$optcfg = &$config['interfaces']['lan'];
+$pconfig['ipaddr'] = $config['interfaces']['lan']['ipaddr'];
+$pconfig['subnet'] = $config['interfaces']['lan']['subnet'];
+
+/* Wireless interface? */
+if (isset($optcfg['wireless'])) {
+       require("interfaces_wlan.inc");
+       wireless_config_init();
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "ipaddr subnet");
+       $reqdfieldsn = explode(",", "IP address,Subnet bit count");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+               $input_errors[] = "A valid IP address must be specified.";
+       }
+       if (($_POST['subnet'] && !is_numeric($_POST['subnet']))) {
+               $input_errors[] = "A valid subnet bit count must be specified.";
+       }
+       
+       /* Wireless interface? */
+       if (isset($optcfg['wireless'])) {
+               $wi_input_errors = wireless_config_post();
+               if ($wi_input_errors) {
+                       $input_errors = array_merge($input_errors, $wi_input_errors);
+               }
+       }
+
+       if (!$input_errors) {
+               $config['interfaces']['lan']['ipaddr'] = $_POST['ipaddr'];
+               $config['interfaces']['lan']['subnet'] = $_POST['subnet'];
+               
+               $dhcpd_was_enabled = 0;
+               if (isset($config['dhcpd']['enable'])) {
+                       unset($config['dhcpd']['enable']);
+                       $dhcpd_was_enabled = 1;
+               }
+                       
+               write_config();
+               touch($d_sysrebootreqd_path);
+               
+               $savemsg = get_std_save_message(0);
+               
+               if ($dhcpd_was_enabled)
+                       $savemsg .= "<br>Note that the DHCP server has been disabled.<br>Please review its configuration " .
+                               "and enable it again prior to rebooting.";
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Interfaces: LAN</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function gen_bits(ipaddr) {
+    if (ipaddr.search(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) != -1) {
+        var adr = ipaddr.split(/\./);
+        if (adr[0] > 255 || adr[1] > 255 || adr[2] > 255 || adr[3] > 255)
+            return "";
+        if (adr[0] == 0 && adr[1] == 0 && adr[2] == 0 && adr[3] == 0)
+            return "";
+               
+               if (adr[0] <= 127)
+                       return "8";
+               else if (adr[0] <= 191)
+                       return "16";
+               else
+                       return "24";
+    }
+    else
+        return "";
+}
+function ipaddr_change() {
+       document.iform.subnet.value = gen_bits(document.iform.ipaddr.value);
+}
+// -->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: LAN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+            <form action="interfaces_lan.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">IP address</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="ipaddr" type="text" class="formfld" id="hostname" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>" onchange="ipaddr_change()">
+                    / 
+                    <select name="subnet" class="formfld" id="subnet">
+                      <?php for ($i = 31; $i > 0; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>>
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select></td>
+                </tr>
+                               <?php /* Wireless interface? */
+                               if (isset($optcfg['wireless']))
+                                       wireless_config_print();
+                               ?>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"><span class="vexpl"><span class="red"><strong>Warning:<br>
+                    </strong></span>after you click &quot;Save&quot;, you must 
+                    reboot your firewall for changes to take effect. You may also 
+                    have to do one or more of the following steps before you can 
+                    access your firewall again: 
+                    <ul>
+                      <li>change the IP address of your computer</li>
+                      <li>renew it's DHCP lease</li>
+                      <li>access the webGUI with the new IP address</li>
+                    </ul>
+                    </span></td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/interfaces_opt.php b/webgui/interfaces_opt.php
new file mode 100644 (file)
index 0000000..b5cb192
--- /dev/null
@@ -0,0 +1,266 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       interfaces_opt.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+unset($index);
+if ($_GET['index'])
+       $index = $_GET['index'];
+else if ($_POST['index'])
+       $index = $_POST['index'];
+       
+if (!$index)
+       exit;
+
+$optcfg = &$config['interfaces']['opt' . $index];
+$pconfig['descr'] = $optcfg['descr'];
+$pconfig['bridge'] = $optcfg['bridge'];
+$pconfig['ipaddr'] = $optcfg['ipaddr'];
+$pconfig['subnet'] = $optcfg['subnet'];
+$pconfig['enable'] = isset($optcfg['enable']);
+
+/* Wireless interface? */
+if (isset($optcfg['wireless'])) {
+       require("interfaces_wlan.inc");
+       wireless_config_init();
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['enable']) {
+       
+               /* description unique? */
+               for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                       if ($i != $index) {
+                               if ($config['interfaces']['opt' . $i]['descr'] == $_POST['descr']) {
+                                       $input_errors[] = "An interface with the specified description already exists.";
+                               }
+                       }
+               }
+               
+               if ($_POST['bridge']) {
+                       /* double bridging? */
+                       for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                               if ($i != $index) {
+                                       if ($config['interfaces']['opt' . $i]['bridge'] == $_POST['bridge']) {
+                                               $input_errors[] = "Optional interface {$i} " . 
+                                                       "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+                                                       "the specified interface.";
+                                       } else if ($config['interfaces']['opt' . $i]['bridge'] == "opt{$index}") {
+                                               $input_errors[] = "Optional interface {$i} " . 
+                                                       "({$config['interfaces']['opt' . $i]['descr']}) is already bridged to " .
+                                                       "this interface.";
+                                       }
+                               }
+                       }
+                       if ($config['interfaces'][$_POST['bridge']]['bridge']) {
+                               $input_errors[] = "The specified interface is already bridged to " .
+                                       "another interface.";
+                       }
+               } else {
+                       $reqdfields = explode(" ", "descr ipaddr subnet");
+                       $reqdfieldsn = explode(",", "Description,IP address,Subnet bit count");
+               
+                       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+               
+                       if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+                               $input_errors[] = "A valid IP address must be specified.";
+                       }
+                       if (($_POST['subnet'] && !is_numeric($_POST['subnet']))) {
+                               $input_errors[] = "A valid subnet bit count must be specified.";
+                       }
+               }
+       }
+       
+       /* Wireless interface? */
+       if (isset($optcfg['wireless'])) {
+               $wi_input_errors = wireless_config_post();
+               if ($wi_input_errors) {
+                       $input_errors = array_merge($input_errors, $wi_input_errors);
+               }
+       }
+       
+       if (!$input_errors) {
+               $optcfg['descr'] = $_POST['descr'];
+               $optcfg['ipaddr'] = $_POST['ipaddr'];
+               $optcfg['subnet'] = $_POST['subnet'];
+               $optcfg['bridge'] = $_POST['bridge'];
+               $optcfg['enable'] = $_POST['enable'] ? true : false;
+                       
+               write_config();
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = interfaces_optional_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Interfaces: Optional <?=$index;?> (<?=htmlspecialchars($optcfg['descr']);?>)</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+       if ((document.iform.bridge.selectedIndex == 0) || enable_over) {
+               document.iform.ipaddr.disabled = 0;
+               document.iform.subnet.disabled = 0;
+       } else {
+               document.iform.ipaddr.disabled = 1;
+               document.iform.subnet.disabled = 1;
+       }
+}
+function gen_bits(ipaddr) {
+    if (ipaddr.search(/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/) != -1) {
+        var adr = ipaddr.split(/\./);
+        if (adr[0] > 255 || adr[1] > 255 || adr[2] > 255 || adr[3] > 255)
+            return 0;
+        if (adr[0] == 0 && adr[1] == 0 && adr[2] == 0 && adr[3] == 0)
+            return 0;
+               
+               if (adr[0] <= 127)
+                       return 23;
+               else if (adr[0] <= 191)
+                       return 15;
+               else
+                       return 7;
+    }
+    else
+        return 0;
+}
+function ipaddr_change() {
+       document.iform.subnet.selectedIndex = gen_bits(document.iform.ipaddr.value);
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: Optional <?=$index;?> (<?=htmlspecialchars($optcfg['descr']);?>)</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if ($optcfg['if']): ?>
+            <form action="interfaces_opt.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+                    <strong>Enable Optional <?=$index;?> interface</strong></td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="30" value="<?=htmlspecialchars($pconfig['descr']);?>">
+                                       <br> <span class="vexpl">Enter a description (name) for the interface here.</span>
+                                </td>
+                               </tr>
+                <tr> 
+                  <td colspan="2" valign="top" height="16"></td>
+                               </tr>
+                               <tr> 
+                  <td colspan="2" valign="top" class="vnsepcell">IP configuration</td>
+                               </tr>
+                               <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Bridge with</td>
+                  <td width="78%" class="vtable">
+<select name="bridge" class="formfld" id="bridge" onChange="enable_change(false)">
+                                       <option <?php if (!$pconfig['bridge']) echo "selected";?> value="">none</option>
+                      <?php $opts = array('lan' => "LAN", 'wan' => "WAN");
+                                               for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                                                       if ($i != $index)
+                                                               $opts['opt' . $i] = "Optional " . $i . " (" .
+                                                                       $config['interfaces']['opt' . $i]['descr'] . ")";
+                                               }
+                                       foreach ($opts as $opt => $optname): ?>
+                      <option <?php if ($opt == $pconfig['bridge']) echo "selected";?> value="<?=htmlspecialchars($opt);?>"> 
+                      <?=htmlspecialchars($optname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> </td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">IP address</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>" onchange="ipaddr_change()">
+                    /
+                       <select name="subnet" class="formfld" id="subnet">
+                                       <?php for ($i = 31; $i > 0; $i--): ?>
+                                       <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>><?=$i;?></option>
+                                       <?php endfor; ?>
+                    </select>
+                                </td>
+                               </tr>
+                               <?php /* Wireless interface? */
+                               if (isset($optcfg['wireless']))
+                                       wireless_config_print();
+                               ?>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="index" type="hidden" value="<?=$index;?>"> 
+                                 <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+                    </strong></span>be sure to add firewall rules to permit traffic 
+                    through the interface. Firewall rules for an interface in 
+                    bridged mode have no effect on packets to hosts other than 
+                    m0n0wall itself, unless &quot;Enable filtering bridge&quot; 
+                    is checked on the <a href="system_advanced.php">System: 
+                    Advanced functions</a> page.</span></td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php else: ?>
+<p><strong>Optional <?=$index;?> has been disabled because there is no OPT<?=$index;?> interface.</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/interfaces_wan.php b/webgui/interfaces_wan.php
new file mode 100644 (file)
index 0000000..f3ecbd0
--- /dev/null
@@ -0,0 +1,421 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       interfaces_wan.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$wancfg = &$config['interfaces']['wan'];
+$optcfg = &$config['interfaces']['wan'];
+
+$pconfig['username'] = $config['pppoe']['username'];
+$pconfig['password'] = $config['pppoe']['password'];
+$pconfig['provider'] = $config['pppoe']['provider'];
+
+$pconfig['pptp_username'] = $config['pptp']['username'];
+$pconfig['pptp_password'] = $config['pptp']['password'];
+$pconfig['pptp_local'] = $config['pptp']['local'];
+$pconfig['pptp_subnet'] = $config['pptp']['subnet'];
+$pconfig['pptp_remote'] = $config['pptp']['remote'];
+
+$pconfig['dhcphostname'] = $wancfg['dhcphostname'];
+
+if ($wancfg['ipaddr'] == "dhcp") {
+       $pconfig['type'] = "DHCP";
+} else if ($wancfg['ipaddr'] == "pppoe") {
+       $pconfig['type'] = "PPPoE";
+} else if ($wancfg['ipaddr'] == "pptp") {
+       $pconfig['type'] = "PPTP";
+} else {
+       $pconfig['type'] = "Static";
+       $pconfig['ipaddr'] = $wancfg['ipaddr'];
+       $pconfig['subnet'] = $wancfg['subnet'];
+       $pconfig['gateway'] = $wancfg['gateway'];
+}
+
+$pconfig['blockpriv'] = isset($wancfg['blockpriv']);
+$pconfig['spoofmac'] = $wancfg['spoofmac'];
+$pconfig['mtu'] = $wancfg['mtu'];
+
+/* Wireless interface? */
+if (isset($optcfg['wireless'])) {
+       require("interfaces_wlan.inc");
+       wireless_config_init();
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['type'] == "Static") {
+               $reqdfields = explode(" ", "ipaddr subnet gateway");
+               $reqdfieldsn = explode(",", "IP address,Subnet bit count,Gateway");
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       } else if ($_POST['type'] == "PPPoE") {
+               $reqdfields = explode(" ", "username password");
+               $reqdfieldsn = explode(",", "PPPoE Username,PPPoE Password");
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       } else if ($_POST['type'] == "PPTP") {
+               $reqdfields = explode(" ", "pptp_username pptp_password pptp_local pptp_subnet pptp_remote");
+               $reqdfieldsn = explode(",", "PPTP Username,PPTP Password,PPTP local IP address,PPTP subnet,PPTP remote IP address");
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       }
+       
+       if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+               $input_errors[] = "A valid IP address must be specified.";
+       }
+       if (($_POST['subnet'] && !is_numeric($_POST['subnet']))) {
+               $input_errors[] = "A valid subnet bit count must be specified.";
+       }
+       if (($_POST['gateway'] && !is_ipaddr($_POST['gateway']))) {
+               $input_errors[] = "A valid gateway must be specified.";
+       }
+       if (($_POST['provider'] && !is_domain($_POST['provider']))) {
+               $input_errors[] = "The service name contains invalid characters.";
+       }
+       if (($_POST['pptp_local'] && !is_ipaddr($_POST['pptp_local']))) {
+               $input_errors[] = "A valid PPTP local IP address must be specified.";
+       }
+       if (($_POST['pptp_subnet'] && !is_numeric($_POST['pptp_subnet']))) {
+               $input_errors[] = "A valid PPTP subnet bit count must be specified.";
+       }
+       if (($_POST['pptp_remote'] && !is_ipaddr($_POST['pptp_remote']))) {
+               $input_errors[] = "A valid PPTP remote IP address must be specified.";
+       }
+       if (($_POST['spoofmac'] && !is_macaddr($_POST['spoofmac']))) {
+               $input_errors[] = "A valid MAC address must be specified.";
+       }
+       if ($_POST['mtu'] && (($_POST['mtu'] < 576) || ($_POST['mtu'] > 1500))) {
+               $input_errors[] = "The MTU must be between 576 and 1500 bytes.";
+       }
+       
+       /* Wireless interface? */
+       if (isset($optcfg['wireless'])) {
+               $wi_input_errors = wireless_config_post();
+               if ($wi_input_errors) {
+                       $input_errors = array_merge($input_errors, $wi_input_errors);
+               }
+       }
+
+       if (!$input_errors) {
+       
+               unset($wancfg['ipaddr']);
+               unset($wancfg['subnet']);
+               unset($wancfg['gateway']);
+               unset($wancfg['dhcphostname']);
+               unset($config['pppoe']['username']);
+               unset($config['pppoe']['password']);
+               unset($config['pppoe']['provider']);
+               unset($config['pptp']['username']);
+               unset($config['pptp']['password']);
+               unset($config['pptp']['local']);
+               unset($config['pptp']['subnet']);
+               unset($config['pptp']['remote']);
+       
+               if ($_POST['type'] == "Static") {
+                       $wancfg['ipaddr'] = $_POST['ipaddr'];
+                       $wancfg['subnet'] = $_POST['subnet'];
+                       $wancfg['gateway'] = $_POST['gateway'];
+               } else if ($_POST['type'] == "DHCP") {
+                       $wancfg['ipaddr'] = "dhcp";
+                       $wancfg['dhcphostname'] = $_POST['dhcphostname'];
+               } else if ($_POST['type'] == "PPPoE") {
+                       $wancfg['ipaddr'] = "pppoe";
+                       $config['pppoe']['username'] = $_POST['username'];
+                       $config['pppoe']['password'] = $_POST['password'];
+                       $config['pppoe']['provider'] = $_POST['provider'];
+               } else if ($_POST['type'] == "PPTP") {
+                       $wancfg['ipaddr'] = "pptp";
+                       $config['pptp']['username'] = $_POST['pptp_username'];
+                       $config['pptp']['password'] = $_POST['pptp_password'];
+                       $config['pptp']['local'] = $_POST['pptp_local'];
+                       $config['pptp']['subnet'] = $_POST['pptp_subnet'];
+                       $config['pptp']['remote'] = $_POST['pptp_remote'];
+               }
+               
+               $wancfg['blockpriv'] = $_POST['blockpriv'] ? true : false;
+               $wancfg['spoofmac'] = $_POST['spoofmac'];
+               $wancfg['mtu'] = $_POST['mtu'];
+                       
+               write_config();
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = interfaces_wan_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Interfaces: WAN</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function type_change() {
+       switch (document.iform.type.selectedIndex) {
+               case 0:
+                       document.iform.username.disabled = 1;
+                       document.iform.password.disabled = 1;
+                       document.iform.provider.disabled = 1;
+                       document.iform.ipaddr.disabled = 0;
+                       document.iform.subnet.disabled = 0;
+                       document.iform.gateway.disabled = 0;
+                       document.iform.pptp_username.disabled = 1;
+                       document.iform.pptp_password.disabled = 1;
+                       document.iform.pptp_local.disabled = 1;
+                       document.iform.pptp_subnet.disabled = 1;
+                       document.iform.pptp_remote.disabled = 1;
+                       document.iform.dhcphostname.disabled = 1;
+                       break;
+               case 1:
+                       document.iform.username.disabled = 1;
+                       document.iform.password.disabled = 1;
+                       document.iform.provider.disabled = 1;
+                       document.iform.ipaddr.disabled = 1;
+                       document.iform.subnet.disabled = 1;
+                       document.iform.gateway.disabled = 1;
+                       document.iform.pptp_username.disabled = 1;
+                       document.iform.pptp_password.disabled = 1;
+                       document.iform.pptp_local.disabled = 1;
+                       document.iform.pptp_subnet.disabled = 1;
+                       document.iform.pptp_remote.disabled = 1;
+                       document.iform.dhcphostname.disabled = 0;
+                       break;
+               case 2:
+                       document.iform.username.disabled = 0;
+                       document.iform.password.disabled = 0;
+                       document.iform.provider.disabled = 0;
+                       document.iform.ipaddr.disabled = 1;
+                       document.iform.subnet.disabled = 1;
+                       document.iform.gateway.disabled = 1;
+                       document.iform.pptp_username.disabled = 1;
+                       document.iform.pptp_password.disabled = 1;
+                       document.iform.pptp_local.disabled = 1;
+                       document.iform.pptp_subnet.disabled = 1;
+                       document.iform.pptp_remote.disabled = 1;
+                       document.iform.dhcphostname.disabled = 1;
+                       break;
+               case 3:
+                       document.iform.username.disabled = 1;
+                       document.iform.password.disabled = 1;
+                       document.iform.provider.disabled = 1;
+                       document.iform.ipaddr.disabled = 1;
+                       document.iform.subnet.disabled = 1;
+                       document.iform.gateway.disabled = 1;
+                       document.iform.pptp_username.disabled = 0;
+                       document.iform.pptp_password.disabled = 0;
+                       document.iform.pptp_local.disabled = 0;
+                       document.iform.pptp_subnet.disabled = 0;
+                       document.iform.pptp_remote.disabled = 0;
+                       document.iform.dhcphostname.disabled = 1;
+                       break;
+       }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Interfaces: WAN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+            <form action="interfaces_wan.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td valign="middle"><strong>Type</strong></td>
+                  <td> <select name="type" class="formfld" id="type" onchange="type_change()">
+                      <?php $opts = split(" ", "Static DHCP PPPoE PPTP");
+                               foreach ($opts as $opt): ?>
+                      <option <?php if ($opt == $pconfig['type']) echo "selected";?>> 
+                      <?=htmlspecialchars($opt);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" height="4"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="vnsepcell">General configuration</td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">MAC address</td>
+                  <td class="vtable"> <input name="spoofmac" type="text" class="formfld" id="spoofmac" size="30" value="<?=htmlspecialchars($pconfig['spoofmac']);?>"> 
+                    <br>
+                    This field can be used to modify (&quot;spoof&quot;) the MAC 
+                    address of the WAN interface<br>
+                    (may be required with some cable connections)<br>
+                    Enter a MAC address in the following format: xx:xx:xx:xx:xx:xx 
+                    or leave blank</td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">MTU</td>
+                  <td class="vtable"> <input name="mtu" type="text" class="formfld" id="mtu" size="8" value="<?=htmlspecialchars($pconfig['mtu']);?>"> 
+                    <br>
+                    If you enter a value in this field, then MSS clamping for 
+                    TCP connections to the value entered above minus 40 (TCP/IP 
+                    header size) will be in effect. If you leave this field blank, 
+                    an MTU of 1492 bytes for PPPoE and 1500 bytes for all other 
+                    connection types will be assumed.</td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" height="16"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="vnsepcell">Static IP configuration</td>
+                </tr>
+                <tr> 
+                  <td width="100" valign="top" class="vncellreq">IP address</td>
+                  <td class="vtable"> <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+                    / 
+                    <select name="subnet" class="formfld" id="subnet">
+                      <?php for ($i = 31; $i > 0; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet']) echo "selected"; ?>> 
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select></td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Gateway</td>
+                  <td class="vtable"> <input name="gateway" type="text" class="formfld" id="gateway" size="20" value="<?=htmlspecialchars($pconfig['gateway']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" height="16"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="vnsepcell">DHCP client configuration</td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">Hostname</td>
+                  <td class="vtable"> <input name="dhcphostname" type="text" class="formfld" id="dhcphostname" size="40" value="<?=htmlspecialchars($pconfig['dhcphostname']);?>">
+                    <br>
+                    The value in this field is sent as the DHCP client identifier 
+                    and hostname when requesting a DHCP lease. Some ISPs may require 
+                    this (for client identification).</td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" height="16"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="vnsepcell">PPPoE configuration</td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Username</td>
+                  <td class="vtable"><input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Password</td>
+                  <td class="vtable"><input name="password" type="text" class="formfld" id="password" size="20" value="<?=htmlspecialchars($pconfig['password']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">Service name</td>
+                  <td class="vtable"><input name="provider" type="text" class="formfld" id="provider" size="20" value="<?=htmlspecialchars($pconfig['provider']);?>"> 
+                    <br> <span class="vexpl">Hint: this field can usually be left 
+                    empty</span></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" height="16"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="vnsepcell">PPTP configuration</td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Username</td>
+                  <td class="vtable"><input name="pptp_username" type="text" class="formfld" id="pptp_username" size="20" value="<?=htmlspecialchars($pconfig['pptp_username']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Password</td>
+                  <td class="vtable"><input name="pptp_password" type="text" class="formfld" id="pptp_password" size="20" value="<?=htmlspecialchars($pconfig['pptp_password']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="100" valign="top" class="vncellreq">Local IP address</td>
+                  <td class="vtable"> <input name="pptp_local" type="text" class="formfld" id="pptp_local" size="20" value="<?=htmlspecialchars($pconfig['pptp_local']);?>">
+                    / 
+                    <select name="pptp_subnet" class="formfld" id="pptp_subnet">
+                      <?php for ($i = 31; $i > 0; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['pptp_subnet']) echo "selected"; ?>> 
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select></td>
+                </tr>
+                <tr> 
+                  <td width="100" valign="top" class="vncellreq">Remote IP address</td>
+                  <td class="vtable"> <input name="pptp_remote" type="text" class="formfld" id="pptp_remote" size="20" value="<?=htmlspecialchars($pconfig['pptp_remote']);?>"> 
+                  </td>
+                </tr>
+                <?php /* Wireless interface? */
+                               if (isset($optcfg['wireless']))
+                                       wireless_config_print();
+                               ?>
+                <tr> 
+                  <td height="16" colspan="2" valign="top"></td>
+                </tr>
+                <tr> 
+                  <td valign="middle">&nbsp;</td>
+                  <td class="vtable"> <input name="blockpriv" type="checkbox" id="blockpriv" value="yes" <?php if ($pconfig['blockpriv'] == "yes") echo "checked"; ?>> 
+                    <strong>Block private networks</strong><br>
+                    When set, this option blocks traffic from IP addresses that 
+                    are reserved for private<br>
+                    networks as per RFC 1918 (10/8, 172.16/12, 192.168/16) as 
+                    well as loopback addresses<br>
+                    (127/8). You should generally leave this option turned on, 
+                    unless your WAN network<br>
+                    lies in such a private address space, too.</td>
+                </tr>
+                <tr> 
+                  <td width="100" valign="top">&nbsp;</td>
+                  <td> &nbsp;<br> <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+type_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/interfaces_wlan.inc b/webgui/interfaces_wlan.inc
new file mode 100644 (file)
index 0000000..8861ce6
--- /dev/null
@@ -0,0 +1,182 @@
+<?php 
+/*
+       interfaces_wlan.inc
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+function wireless_config_init() {
+       global $optcfg, $pconfig;
+       
+       $pconfig['mode'] = $optcfg['wireless']['mode'];
+       $pconfig['ssid'] = $optcfg['wireless']['ssid'];
+       $pconfig['stationname'] = $optcfg['wireless']['stationname'];
+       $pconfig['channel'] = $optcfg['wireless']['channel'];
+       $pconfig['wep_enable'] = isset($optcfg['wireless']['wep']['enable']);
+       
+       if (is_array($optcfg['wireless']['wep']['key'])) {
+               $i = 1;
+               foreach ($optcfg['wireless']['wep']['key'] as $wepkey) {
+                       $pconfig['key' . $i] = $wepkey['value'];
+                       if (isset($wepkey['txkey']))
+                               $pconfig['txkey'] = $i;
+                       $i++;
+               }
+               if (!isset($wepkey['txkey']))
+                       $pconfig['txkey'] = 1;
+       }
+}
+
+function wireless_config_post() {
+       global $optcfg, $pconfig;
+
+       unset($input_errors);
+
+       /* input validation */
+       if ($_POST['enable']) {
+               $reqdfields = explode(" ", "mode ssid channel");
+               $reqdfieldsn = explode(",", "Mode,SSID,Channel");
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+               
+               if (!$input_errors) {
+                       /* bridge check (hostap only!) */
+                       if ($pconfig['bridge'] && ($pconfig['mode'] != "hostap"))
+                               $input_errors[] = "Bridging a wireless interface is only possible in hostap mode.";
+               }
+       }
+
+       if (!$input_errors) {
+       
+               $optcfg['wireless']['mode'] = $_POST['mode'];
+               $optcfg['wireless']['ssid'] = $_POST['ssid'];
+               $optcfg['wireless']['stationname'] = $_POST['stationname'];
+               $optcfg['wireless']['channel'] = $_POST['channel'];
+               $optcfg['wireless']['wep']['enable'] = $_POST['wep_enable'] ? true : false;
+               
+               $optcfg['wireless']['wep']['key'] = array();
+               for ($i = 1; $i <= 4; $i++) {
+                       if ($_POST['key' . $i]) {
+                               $newkey = array();
+                               $newkey['value'] = $_POST['key' . $i];
+                               if ($_POST['txkey'] == $i)
+                                       $newkey['txkey'] = true;
+                               $optcfg['wireless']['wep']['key'][] = $newkey;
+                       }
+               }
+       }
+       
+       return $input_errors;
+}
+
+function wireless_config_print() {
+       global $optcfg, $pconfig;
+?>
+                <tr> 
+                  <td colspan="2" valign="top" height="16"></td>
+                               </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="vnsepcell">Wireless configuration</td>
+                               </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Mode</td>
+                  <td class="vtable"> <select name="mode" class="formfld" id="mode">
+                      <?php 
+                                               $opts = array();
+                                               if (strstr($optcfg['if'], "wi"))
+                                                       $opts[] = "hostap";
+                                               $opts[] = "BSS";
+                                               $opts[] = "IBSS";
+                               foreach ($opts as $opt): ?>
+                      <option <?php if ($opt == $pconfig['mode']) echo "selected";?>> 
+                      <?=htmlspecialchars($opt);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    Note: IBSS mode is sometimes also called &quot;ad-hoc&quot; 
+                    mode;<br>
+                    BSS mode is also known as &quot;infrastructure&quot; mode</td>
+                               </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">SSID</td>
+                  <td class="vtable"><input name="ssid" type="text" class="formfld" id="ssid" size="20" value="<?=htmlspecialchars($pconfig['ssid']);?>">
+                  </td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncellreq">Channel</td>
+                  <td class="vtable"><select name="channel" class="formfld" id="channel">
+                      <?php
+                                         for ($i = 0; $i <= 14; $i++): ?>
+                      <option <?php if ($i == $pconfig['channel']) echo "selected";?>>
+                      <? echo($i==0 ? "Auto" : $i) ?>
+                      </option>
+                      <?php endfor; ?>
+                    </select></td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">Station name</td>
+                  <td class="vtable"><input name="stationname" type="text" class="formfld" id="stationname" size="20" value="<?=htmlspecialchars($pconfig['stationname']);?>"> 
+                    <br>
+                    Hint: this field can usually be left blank</td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">WEP</td>
+                  <td class="vtable"> <input name="wep_enable" type="checkbox" id="wep_enable" value="yes" <?php if ($pconfig['wep_enable'] == "yes") echo "checked"; ?>> 
+                    <strong>Enable WEP</strong><br>
+                    &nbsp; <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>&nbsp;</td>
+                        <td>&nbsp;</td>
+                        <td>&nbsp;TX key&nbsp;</td>
+                      </tr>
+                      <tr> 
+                        <td>Key 1:&nbsp;&nbsp;</td>
+                        <td> <input name="key1" type="text" class="formfld" id="key1" size="30" value="<?=htmlspecialchars($pconfig['key1']);?>"></td>
+                        <td align="center"> <input name="txkey" type="radio" value="1" <?php if ($pconfig['txkey'] == 1) echo "checked";?>> 
+                        </td>
+                      </tr>
+                      <tr> 
+                        <td>Key 2:&nbsp;&nbsp;</td>
+                        <td> <input name="key2" type="text" class="formfld" id="key2" size="30" value="<?=htmlspecialchars($pconfig['key2']);?>"></td>
+                        <td align="center"> <input name="txkey" type="radio" value="2" <?php if ($pconfig['txkey'] == 2) echo "checked";?>></td>
+                      </tr>
+                      <tr> 
+                        <td>Key 3:&nbsp;&nbsp;</td>
+                        <td> <input name="key3" type="text" class="formfld" id="key3" size="30" value="<?=htmlspecialchars($pconfig['key3']);?>"></td>
+                        <td align="center"> <input name="txkey" type="radio" value="3" <?php if ($pconfig['txkey'] == 3) echo "checked";?>></td>
+                      </tr>
+                      <tr> 
+                        <td>Key 4:&nbsp;&nbsp;</td>
+                        <td> <input name="key4" type="text" class="formfld" id="key4" size="30" value="<?=htmlspecialchars($pconfig['key4']);?>"></td>
+                        <td align="center"> <input name="txkey" type="radio" value="4" <?php if ($pconfig['txkey'] == 4) echo "checked";?>></td>
+                      </tr>
+                    </table>
+                    <br>
+                    40 (64) bit keys may be entered as 5 ASCII characters or 10 
+                    hex digits preceded by '0x'.<br>
+                    104 (128) bit keys may be entered as 13 ASCII characters or 
+                    26 hex digits preceded by '0x'.</td>
+                </tr>
+<?php } ?>
diff --git a/webgui/license.php b/webgui/license.php
new file mode 100644 (file)
index 0000000..851d94b
--- /dev/null
@@ -0,0 +1,148 @@
+#!/usr/local/bin/php
+<?php require("guiconfig.inc"); 
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - License</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">License</p>
+            <p><strong>m0n0wall is Copyright &copy; 2002-2004 by Manuel Kasper 
+              (<a href="mailto:mk@neon1.net">mk@neon1.net</a>).<br>
+              All rights reserved.</strong></p>
+            <p> Redistribution and use in source and binary forms, with or without<br>
+              modification, are permitted provided that the following conditions 
+              are met:<br>
+              <br>
+              1. Redistributions of source code must retain the above copyright 
+              notice,<br>
+              this list of conditions and the following disclaimer.<br>
+              <br>
+              2. Redistributions in binary form must reproduce the above copyright<br>
+              notice, this list of conditions and the following disclaimer in 
+              the<br>
+              documentation and/or other materials provided with the distribution.<br>
+              <br>
+              <strong>THIS SOFTWARE IS PROVIDED &quot;AS IS'' AND ANY EXPRESS 
+              OR IMPLIED WARRANTIES,<br>
+              INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY<br>
+              AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT 
+              SHALL THE<br>
+              AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, 
+              EXEMPLARY,<br>
+              OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT 
+              OF<br>
+              SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 
+              BUSINESS<br>
+              INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER 
+              IN<br>
+              CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)<br>
+              ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
+              OF THE<br>
+              POSSIBILITY OF SUCH DAMAGE</strong>.</p>
+            <hr size="1">
+            <p>The following persons have contributed code to m0n0wall:</p>
+            <p>Bob Zoller (<a href="mailto:bob@kludgebox.com">bob@kludgebox.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Diagnostics: Ping 
+              function; WLAN channel auto-select; DNS forwarder</font></em><br>
+              <br>
+              Michael Mee (<a href="mailto:mikemee2002@pobox.com">mikemee2002@pobox.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Timezone and NTP 
+              client support</font></em><br>
+              <br>
+              Magne Andreassen (<a href="mailto:magne.andreassen@bluezone.no">magne.andreassen@bluezone.no</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Remote syslog'ing; 
+              some code bits for DHCP server on optional interfaces</font></em><br>
+              <br>
+              Rob Whyte (<a href="mailto:rob@g-labs.com">rob@g-labs.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Idea/code bits 
+              for encrypted webGUI passwords; minimalized SNMP agent</font></em><br>
+              <br>
+              Petr Verner (<a href="mailto:verner@ipps.cz">verner@ipps.cz</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Advanced outbound 
+              NAT: destination selection</font></em><br>
+              <br>
+              Bruce A. Mah (<a href="mailto:bmah@acm.org">bmah@acm.org</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Filtering bridge 
+              patches </font></em><br>
+              <br>
+              Jim McBeath (<a href="mailto:monowall@j.jimmc.org">monowall@j.jimmc.org</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">Filter rule patches 
+              (ordering, block/pass, disabled); better status page;<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;webGUI assign network ports page </font></em><br>
+              <br>
+              Chris Olive (<a href="mailto:chris@technologEase.com">chris@technologEase.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">enhanced &quot;execute 
+              command&quot; page</font></em><br>
+              <br>
+              Pauline Middelink (<a href="mailto:middelink@polyware.nl">middelink@polyware.nl</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">DHCP client: send hostname patch</font></em><br>
+              <br>
+              Björn Pålsson (<a href="mailto:bjorn@networksab.com">bjorn@networksab.com</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">DHCP lease list page</font></em><br>
+              <br>
+              Peter Allgeyer (<a href="mailto:allgeyer@web.de">allgeyer@web.de</a>)<br>
+              &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">&quot;reject&quot; type filter rules</font></em></p>
+            <hr size="1">
+            <p>m0n0wall is based upon/includes various free software packages, 
+              listed below.<br>
+              The author of m0n0wall would like to thank the authors of these 
+              software packages for their efforts.</p>
+            <p>FreeBSD (<a href="http://www.freebsd.org" target="_blank">http://www.freebsd.org</a>)<br>
+              Copyright &copy; 1994-2003 FreeBSD, Inc. All rights reserved.<br>
+              <br>
+              This product includes PHP, freely available from <a href="http://www.php.net/" target="_blank">http://www.php.net</a>.<br>
+              Copyright &copy; 1999 - 2003 The PHP Group. All rights reserved.<br>
+              <br>
+              mini_httpd (<a href="http://www.acme.com/software/mini_httpd" target="_blank">http://www.acme.com/software/mini_httpd)</a><br>
+              Copyright &copy; 1999, 2000 by Jef Poskanzer &lt;jef@acme.com&gt;. 
+              All rights reserved.<br>
+              <br>
+              ISC DHCP server (<a href="http://www.isc.org/products/DHCP/" target="_blank">http://www.isc.org/products/DHCP</a>)<br>
+              Copyright &copy; 1996-2003 Internet Software Consortium. All rights 
+              reserved.<br>
+              <br>
+              ipfilter (<a href="http://www.ipfilter.org" target="_blank">http://www.ipfilter.org</a>)<br>
+              Copyright &copy; 1993-2002 by Darren Reed.<br>
+              <br>
+              MPD - Multi-link PPP daemon for FreeBSD (<a href="http://www.dellroad.org/mpd" target="_blank">http://www.dellroad.org/mpd</a>)<br>
+              Copyright &copy; 1995-1999 Whistle Communications, Inc. All rights 
+              reserved. <br>
+              <br>
+              ez-ipupdate (<a href="http://www.gusnet.cx/proj/ez-ipupdate/" target="_blank">http://www.gusnet.cx/proj/ez-ipupdate</a>)<br>
+              Copyright &copy; 1998-2001 Angus Mackay. All rights reserved.<br>
+              <br>
+              Circular log support for FreeBSD syslogd (<a href="http://software.wwwi.com/syslogd/" target="_blank">http://software.wwwi.com/syslogd</a>)<br>
+              Copyright &copy; 2001 Jeff Wheelhouse (jdw@wwwi.com)<br>
+              <br>
+              Dnsmasq - a DNS forwarder for NAT firewalls (<a href="http://www.thekelleys.org.uk" target="_blank">http://www.thekelleys.org.uk</a>)<br>
+              Copyright &copy; 2000-2003 Simon Kelley.<br>
+              <br>
+              Racoon (<a href="http://www.kame.net/racoon" target="_blank">http://www.kame.net/racoon</a>)<br>
+              Copyright &copy; 1995-2002 WIDE Project. All rights reserved.<br>
+              <br>
+              msntp (<a href="http://www.hpcf.cam.ac.uk/export" target="_blank">http://www.hpcf.cam.ac.uk/export</a>)<br>
+              Copyright &copy; 1996, 1997, 2000 N.M. Maclaren, University of Cambridge. 
+              All rights reserved.<br>
+              <br>
+              UCD-SNMP (<a href="http://www.ece.ucdavis.edu/ucd-snmp" target="_blank">http://www.ece.ucdavis.edu/ucd-snmp</a>)<br>
+              Copyright &copy; 1989, 1991, 1992 by Carnegie Mellon University.<br>
+              Copyright &copy; 1996, 1998-2000 The Regents of the University of 
+              California. All rights reserved.<br>
+              Copyright &copy; 2001-2002, Network Associates Technology, Inc. 
+              All rights reserved.<br>
+              Portions of this code are copyright &copy; 2001-2002, Cambridge 
+              Broadband Ltd. All rights reserved.<br>
+              <br>
+              choparp (<a href="http://choparp.sourceforge.net/" target="_blank">http://choparp.sourceforge.net</a>)<br>
+              Copyright &copy; 1997 Takamichi Tateoka (tree@mma.club.uec.ac.jp)<br>
+                         Copyright
+&copy; 2002 Thomas Quinot (thomas@cuivre.fr.eu.org)
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/log.gif b/webgui/log.gif
new file mode 100644 (file)
index 0000000..bd8660f
Binary files /dev/null and b/webgui/log.gif differ
diff --git a/webgui/log_d.gif b/webgui/log_d.gif
new file mode 100644 (file)
index 0000000..2c67b29
Binary files /dev/null and b/webgui/log_d.gif differ
diff --git a/webgui/log_s.gif b/webgui/log_s.gif
new file mode 100644 (file)
index 0000000..2179b8d
Binary files /dev/null and b/webgui/log_s.gif differ
diff --git a/webgui/log_s_d.gif b/webgui/log_s_d.gif
new file mode 100644 (file)
index 0000000..2c17d78
Binary files /dev/null and b/webgui/log_s_d.gif differ
diff --git a/webgui/logo.gif b/webgui/logo.gif
new file mode 100644 (file)
index 0000000..3422a59
Binary files /dev/null and b/webgui/logo.gif differ
diff --git a/webgui/logobig.gif b/webgui/logobig.gif
new file mode 100644 (file)
index 0000000..dc2b78b
Binary files /dev/null and b/webgui/logobig.gif differ
diff --git a/webgui/out.gif b/webgui/out.gif
new file mode 100644 (file)
index 0000000..d94474d
Binary files /dev/null and b/webgui/out.gif differ
diff --git a/webgui/pass.gif b/webgui/pass.gif
new file mode 100644 (file)
index 0000000..1526e31
Binary files /dev/null and b/webgui/pass.gif differ
diff --git a/webgui/pass_d.gif b/webgui/pass_d.gif
new file mode 100644 (file)
index 0000000..47087d4
Binary files /dev/null and b/webgui/pass_d.gif differ
diff --git a/webgui/plus.gif b/webgui/plus.gif
new file mode 100644 (file)
index 0000000..025e9b2
Binary files /dev/null and b/webgui/plus.gif differ
diff --git a/webgui/reboot.php b/webgui/reboot.php
new file mode 100644 (file)
index 0000000..548d4f4
--- /dev/null
@@ -0,0 +1,66 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       reboot.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if ($_POST) {
+       if ($_POST['Submit'] != " No ") {
+               system_reboot();
+               $rebootmsg = "The system is rebooting now. This may take one minute.";
+       } else {
+               header("Location: index.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Reboot system</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Reboot system</p>
+<?php if ($rebootmsg): echo print_info_box(htmlspecialchars($rebootmsg)); else: ?>
+      <form action="reboot.php" method="post">
+        <p><strong>Are you sure you want to reboot the system?</strong></p>
+        <p> 
+          <input name="Submit" type="submit" class="formbtn" value=" Yes ">
+          <input name="Submit" type="submit" class="formbtn" value=" No ">
+        </p>
+      </form>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/reject.gif b/webgui/reject.gif
new file mode 100644 (file)
index 0000000..852e37c
Binary files /dev/null and b/webgui/reject.gif differ
diff --git a/webgui/reject_d.gif b/webgui/reject_d.gif
new file mode 100644 (file)
index 0000000..1300200
Binary files /dev/null and b/webgui/reject_d.gif differ
diff --git a/webgui/services_dhcp.php b/webgui/services_dhcp.php
new file mode 100644 (file)
index 0000000..6c08690
--- /dev/null
@@ -0,0 +1,325 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_dhcp.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$if = $_GET['if'];
+if ($_POST['if'])
+       $if = $_POST['if'];
+       
+$iflist = array("lan" => "LAN");
+
+for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+       $oc = $config['interfaces']['opt' . $i];
+       
+       if (isset($oc['enable']) && $oc['if'] && (!$oc['bridge'])) {
+               $iflist['opt' . $i] = $oc['descr'];
+       }
+}
+
+if (!$if || !isset($iflist[$if]))
+       $if = "lan";
+
+$pconfig['range_from'] = $config['dhcpd'][$if]['range']['from'];
+$pconfig['range_to'] = $config['dhcpd'][$if]['range']['to'];
+$pconfig['deftime'] = $config['dhcpd'][$if]['defaultleasetime'];
+$pconfig['maxtime'] = $config['dhcpd'][$if]['maxleasetime'];
+list($pconfig['wins1'],$pconfig['wins2']) = $config['dhcpd'][$if]['winsserver'];
+$pconfig['enable'] = isset($config['dhcpd'][$if]['enable']);
+
+$ifcfg = $config['interfaces'][$if];
+
+if (!is_array($config['dhcpd'][$if]['staticmap'])) {
+       $config['dhcpd'][$if]['staticmap'] = array();
+}
+staticmaps_sort($if);
+$a_maps = &$config['dhcpd'][$if]['staticmap'];
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['enable']) {
+               $reqdfields = explode(" ", "range_from range_to");
+               $reqdfieldsn = explode(",", "Range begin,Range end");
+               
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+               
+               if (($_POST['range_from'] && !is_ipaddr($_POST['range_from']))) {
+                       $input_errors[] = "A valid range must be specified.";
+               }
+               if (($_POST['range_to'] && !is_ipaddr($_POST['range_to']))) {
+                       $input_errors[] = "A valid range must be specified.";
+               }
+               if (($_POST['wins1'] && !is_ipaddr($_POST['wins1'])) || ($_POST['wins2'] && !is_ipaddr($_POST['wins2']))) {
+                       $input_errors[] = "A valid IP address must be specified for the primary/secondary WINS server.";
+               }
+               if ($_POST['deftime'] && (!is_numeric($_POST['deftime']) || ($_POST['deftime'] < 60))) {
+                       $input_errors[] = "The default lease time must be at least 60 seconds.";
+               }
+               if ($_POST['maxtime'] && (!is_numeric($_POST['maxtime']) || ($_POST['maxtime'] < 60) || ($_POST['maxtime'] <= $_POST['deftime']))) {
+                       $input_errors[] = "The maximum lease time must be at least 60 seconds and higher than the default lease time.";
+               }
+               
+               if (!$input_errors) {
+                       /* make sure the range lies within the current subnet */
+                       $subnet_start = (ip2long($ifcfg['ipaddr']) & gen_subnet_mask_long($ifcfg['subnet']));
+                       $subnet_end = (ip2long($ifcfg['ipaddr']) | (~gen_subnet_mask_long($ifcfg['subnet'])));
+                       
+                       if ((ip2long($_POST['range_from']) < $subnet_start) || (ip2long($_POST['range_from']) > $subnet_end) ||
+                           (ip2long($_POST['range_to']) < $subnet_start) || (ip2long($_POST['range_to']) > $subnet_end)) {
+                               $input_errors[] = "The specified range lies outside of the current subnet.";    
+                       }
+                       
+                       if (ip2long($_POST['range_from']) > ip2long($_POST['range_to']))
+                               $input_errors[] = "The range is invalid (first element higher than second element).";
+               }
+       }
+
+       if (!$input_errors) {
+               $config['dhcpd'][$if]['range']['from'] = $_POST['range_from'];
+               $config['dhcpd'][$if]['range']['to'] = $_POST['range_to'];
+               $config['dhcpd'][$if]['defaultleasetime'] = $_POST['deftime'];
+               $config['dhcpd'][$if]['maxleasetime'] = $_POST['maxtime'];
+               $config['dhcpd'][$if]['enable'] = $_POST['enable'] ? true : false;
+               
+               unset($config['dhcpd'][$if]['winsserver']);
+               if ($_POST['wins1'])
+                       $config['dhcpd'][$if]['winsserver'][] = $_POST['wins1'];
+               if ($_POST['wins2'])
+                       $config['dhcpd'][$if]['winsserver'][] = $_POST['wins2'];
+                       
+               write_config();
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = services_dhcpd_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               
+               if ($retval == 0) {
+                       if (file_exists($d_staticmapsdirty_path))
+                               unlink($d_staticmapsdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_maps[$_GET['id']]) {
+               unset($a_maps[$_GET['id']]);
+               write_config();
+               touch($d_staticmapsdirty_path);
+               header("Location: services_dhcp.php?if={$if}");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: DHCP</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+       if (document.iform.enable.checked || enable_over) {
+               document.iform.range_from.disabled = 0;
+               document.iform.range_to.disabled = 0;
+               document.iform.wins1.disabled = 0;
+               document.iform.wins2.disabled = 0;
+               document.iform.deftime.disabled = 0;
+               document.iform.maxtime.disabled = 0;
+       } else {
+               document.iform.range_from.disabled = 1;
+               document.iform.range_to.disabled = 1;
+               document.iform.wins1.disabled = 1;
+               document.iform.wins2.disabled = 1;
+               document.iform.deftime.disabled = 1;
+               document.iform.maxtime.disabled = 1;
+       }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DHCP</p>
+<form action="services_dhcp.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_staticmapsdirty_path)): ?><p>
+<?php print_info_box_np("The static mapping configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+<?php $i = 1; foreach ($iflist as $ifent => $ifname):
+       if ($ifent == $if): ?>
+    <td nowrap class="tabact"><?=htmlspecialchars($ifname);?></td>
+<?php else: ?>
+    <td nowrap class="tabinact"><a href="services_dhcp.php?if=<?=$ifent;?>" class="tblnk"><?=htmlspecialchars($ifname);?></a></td>
+<?php endif; ?>
+<?php $i++; endforeach; ?>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="<?=$i;?>" class="tabcont">                    
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                      <tr> 
+                        <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                        <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+                          <strong>Enable DHCP server on 
+                          <?=htmlspecialchars($iflist[$if]);?>
+                          interface</strong></td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncellreq">Subnet</td>
+                        <td width="78%" class="vtable"> 
+                          <?=gen_subnet($ifcfg['ipaddr'], $ifcfg['subnet']);?>
+                        </td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncellreq">Subnet 
+                          mask</td>
+                        <td width="78%" class="vtable"> 
+                          <?=gen_subnet_mask($ifcfg['subnet']);?>
+                        </td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncellreq">Available 
+                          range</td>
+                        <td width="78%" class="vtable"> 
+                          <?=long2ip(ip2long($ifcfg['ipaddr']) & gen_subnet_mask_long($ifcfg['subnet']));?>
+                          - 
+                          <?=long2ip(ip2long($ifcfg['ipaddr']) | (~gen_subnet_mask_long($ifcfg['subnet']))); ?>
+                        </td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncellreq">Range</td>
+                        <td width="78%" class="vtable"> 
+                          <input name="range_from" type="text" class="formfld" id="range_from" size="20" value="<?=htmlspecialchars($pconfig['range_from']);?>"> 
+                          &nbsp;to&nbsp; <input name="range_to" type="text" class="formfld" id="range_to" size="20" value="<?=htmlspecialchars($pconfig['range_to']);?>"></td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncell">WINS servers</td>
+                        <td width="78%" class="vtable"> 
+                          <input name="wins1" type="text" class="formfld" id="wins1" size="20" value="<?=htmlspecialchars($pconfig['wins1']);?>"><br>
+                          <input name="wins2" type="text" class="formfld" id="wins2" size="20" value="<?=htmlspecialchars($pconfig['wins2']);?>"></td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncell">Default lease 
+                          time</td>
+                        <td width="78%" class="vtable"> 
+                          <input name="deftime" type="text" class="formfld" id="deftime" size="10" value="<?=htmlspecialchars($pconfig['deftime']);?>">
+                          seconds<br>
+                          This is used for clients that do not ask for a specific 
+                          expiration time.<br>
+                          The default is 7200 seconds.</td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top" class="vncell">Maximum lease 
+                          time</td>
+                        <td width="78%" class="vtable"> 
+                          <input name="maxtime" type="text" class="formfld" id="maxtime" size="10" value="<?=htmlspecialchars($pconfig['maxtime']);?>">
+                          seconds<br>
+                          This is the maximum lease time for clients that ask 
+                          for a specific expiration time.<br>
+                          The default is 86400 seconds.</td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top">&nbsp;</td>
+                        <td width="78%"> 
+                          <input name="if" type="hidden" value="<?=$if;?>"> 
+                          <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                        </td>
+                      </tr>
+                      <tr> 
+                        <td width="22%" valign="top">&nbsp;</td>
+                        <td width="78%"> <p><span class="vexpl"><span class="red"><strong>Note:<br>
+                            </strong></span>The DNS servers entered in <a href="system.php">System: 
+                            General setup</a> (or the <a href="services_dnsmasq.php">DNS 
+                            forwarder</a>, if enabled) </span><span class="vexpl">will 
+                            be assigned to clients by the DHCP server.<br>
+                            <br>
+                            The DHCP lease table can be viewed on the <a href="diag_dhcp_leases.php">Diagnostics: 
+                            DHCP leases</a> page.<br>
+                            <br>
+                            You may enter static mappings between IP and MAC addresses 
+                            below. </span></p></td>
+                      </tr>
+                    </table>
+                                       &nbsp;<br>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td width="20%" class="listhdrr">IP address</td>
+                  <td width="35%" class="listhdrr">MAC address </td>
+                  <td width="35%" class="listhdrr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_maps as $mapent): ?>
+                <tr>
+                  <td class="listlr">
+                    <?=htmlspecialchars($mapent['ipaddr']);?>
+                  </td>
+                  <td class="listr">
+                    <?=htmlspecialchars($mapent['mac']);?>
+                  </td>
+                  <td class="listbg">
+                    <?=htmlspecialchars($mapent['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" nowrap class="list"> <a href="services_dhcp_edit.php?if=<?=$if;?>&id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="services_dhcp.php?if=<?=$if;?>&act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this mapping?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="3"></td>
+                  <td class="list"> <a href="services_dhcp_edit.php?if=<?=$if;?>"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+    </td>
+  </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/services_dhcp_edit.php b/webgui/services_dhcp_edit.php
new file mode 100644 (file)
index 0000000..86ce158
--- /dev/null
@@ -0,0 +1,174 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_dhcp_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$if = $_GET['if'];
+if ($_POST['if'])
+       $if = $_POST['if'];
+       
+if (!$if) {
+       header("Location: services_dhcp.php");
+       exit;
+}
+
+if (!is_array($config['dhcpd'][$if]['staticmap'])) {
+       $config['dhcpd'][$if]['staticmap'] = array();
+}
+staticmaps_sort($if);
+$a_maps = &$config['dhcpd'][$if]['staticmap'];
+$ifcfg = &$config['interfaces'][$if];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_maps[$id]) {
+       $pconfig['mac'] = $a_maps[$id]['mac'];
+       $pconfig['ipaddr'] = $a_maps[$id]['ipaddr'];
+       $pconfig['descr'] = $a_maps[$id]['descr'];
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "mac ipaddr");
+       $reqdfieldsn = explode(",", "MAC address,IP address");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['ipaddr'] && !is_ipaddr($_POST['ipaddr']))) {
+               $input_errors[] = "A valid IP address must be specified.";
+       }
+       if (($_POST['mac'] && !is_macaddr($_POST['mac']))) {
+               $input_errors[] = "A valid MAC address must be specified.";
+       }
+
+       /* check for overlaps */
+       foreach ($a_maps as $mapent) {
+               if (isset($id) && ($a_maps[$id]) && ($a_maps[$id] === $mapent))
+                       continue;
+
+               if (($mapent['mac'] == $_POST['mac']) || (ip2long($mapent['ipaddr']) == ip2long($_POST['ipaddr']))) {
+                       $input_errors[] = "This IP or MAC address already exists.";
+                       break;
+               }
+       }
+               
+       /* make sure it's not within the dynamic subnet */
+       $dynsubnet_start = ip2long($config['dhcpd'][$if]['range']['from']);
+       $dynsubnet_end = ip2long($config['dhcpd'][$if]['range']['to']);
+       $lansubnet_start = (ip2long($ifcfg['ipaddr']) & gen_subnet_mask_long($ifcfg['subnet']));
+       $lansubnet_end = (ip2long($ifcfg['ipaddr']) | (~gen_subnet_mask_long($ifcfg['subnet'])));
+       
+       if ((ip2long($_POST['ipaddr']) >= $dynsubnet_start) &&
+                       (ip2long($_POST['ipaddr']) <= $dynsubnet_end)) {
+               $input_errors[] = "Static IP addresses may not lie within the dynamic client range.";
+       }
+       if ((ip2long($_POST['ipaddr']) < $lansubnet_start) ||
+               (ip2long($_POST['ipaddr']) > $lansubnet_end)) {
+               $input_errors[] = "The IP address must lie in the {$ifcfg['descr']} subnet.";
+       }
+
+       if (!$input_errors) {
+               $mapent = array();
+               $mapent['mac'] = $_POST['mac'];
+               $mapent['ipaddr'] = $_POST['ipaddr'];
+               $mapent['descr'] = $_POST['descr'];
+
+               if (isset($id) && $a_maps[$id])
+                       $a_maps[$id] = $mapent;
+               else
+                       $a_maps[] = $mapent;
+               
+               touch($d_staticmapsdirty_path);
+               
+               write_config();
+               
+               header("Location: services_dhcp.php?if={$if}");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: DHCP: Edit static mapping</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DHCP: Edit static mapping</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="services_dhcp_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">IP address</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">MAC address</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="mac" type="text" class="formfld" id="mac" size="30" value="<?=htmlspecialchars($pconfig['mac']);?>"> 
+                    <br>
+                    <span class="vexpl">Enter a MAC address in the following format: 
+                    xx:xx:xx:xx:xx:xx</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_maps[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                    <input name="if" type="hidden" value="<?=$if;?>"> 
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/services_dnsmasq.php b/webgui/services_dnsmasq.php
new file mode 100644 (file)
index 0000000..af4acd0
--- /dev/null
@@ -0,0 +1,168 @@
+#!/usr/local/bin/php
+<?php
+/*
+       services_dnsmasq.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Bob Zoller <bob@kludgebox.com> and Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['enable'] = isset($config['dnsmasq']['enable']);
+$pconfig['regdhcp'] = isset($config['dnsmasq']['regdhcp']);
+
+if (!is_array($config['dnsmasq']['hosts'])) {
+       $config['dnsmasq']['hosts'] = array();
+}
+hosts_sort();
+$a_hosts = &$config['dnsmasq']['hosts'];
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       $config['dnsmasq']['enable'] = ($_POST['enable']) ? true : false;
+       $config['dnsmasq']['regdhcp'] = ($_POST['regdhcp']) ? true : false;
+
+       write_config();
+       
+       $retval = 0;
+       if (!file_exists($d_sysrebootreqd_path)) {
+               config_lock();
+               $retval = services_dnsmasq_configure();
+               config_unlock();
+       }
+       $savemsg = get_std_save_message($retval);
+
+       if ($retval == 0) {
+               if (file_exists($d_hostsdirty_path))
+                       unlink($d_hostsdirty_path);
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_hosts[$_GET['id']]) {
+               unset($a_hosts[$_GET['id']]);
+               write_config();
+               touch($d_hostsdirty_path);
+               header("Location: services_dnsmasq.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: DNS forwarder</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DNS forwarder</p>
+<form action="services_dnsmasq.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_hostsdirty_path)): ?><p>
+<?php print_info_box_np("The DNS forwarder configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+                         <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td class="vtable"><p> 
+                      <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable'] == "yes") echo "checked";?>>
+                      <strong>Enable DNS forwarder<br>
+                      </strong></p></td>
+                </tr>
+                <tr> 
+                  <td class="vtable"><p> 
+                      <input name="regdhcp" type="checkbox" id="regdhcp" value="yes" <?php if ($pconfig['regdhcp'] == "yes") echo "checked";?>>
+                      <strong>Register DHCP leases in DNS forwarder<br>
+                      </strong>If this option is set, then machines that specify 
+                      their hostname when requesting a DHCP lease will be registered 
+                      in the DNS forwarder, so that their name can be resolved. 
+                      You should also set the domain in <a href="system.php">System: 
+                      General setup</a> to the proper value.</p>
+                    </td>
+                </tr>
+                <tr> 
+                  <td> <input name="submit" type="submit" class="formbtn" value="Save"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td><p><span class="vexpl"><span class="red"><strong>Note:<br>
+                      </strong></span>If the DNS forwarder is enabled, the DHCP 
+                      service (if enabled) will automatically serve the LAN IP 
+                      address as a DNS server to DHCP clients so they will use 
+                      the forwarder. The DNS forwarder will use the DNS servers 
+                      entered in <a href="system.php">System: General setup</a> 
+                      or those obtained via DHCP or PPP on WAN if the &quot;Allow 
+                      DNS server list to be overridden by DHCP/PPP on WAN&quot;</span> 
+                      is checked. If you don't use that option (or if you use 
+                      a static IP address on WAN), you must manually specify at 
+                      least one DNS server on the <a href="system.php">System: 
+                      General setup</a> page.<br>
+                      <br>
+                      You may enter records that override the results from the 
+                      forwarders below.</p></td>
+                </tr>
+              </table>
+              &nbsp;<br>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td width="20%" class="listhdrr">Host</td>
+                  <td width="25%" class="listhdrr">Domain</td>
+                  <td width="20%" class="listhdrr">IP</td>
+                  <td width="25%" class="listhdrr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_hosts as $hostent): ?>
+                <tr>
+                  <td class="listlr">
+                    <?=strtolower($hostent['host']);?>&nbsp;
+                  </td>
+                  <td class="listr">
+                    <?=strtolower($hostent['domain']);?>&nbsp;
+                  </td>
+                  <td class="listr">
+                    <?=$hostent['ip'];?>&nbsp;
+                  </td>
+                  <td class="listbg">
+                    <?=htmlspecialchars($hostent['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" nowrap class="list"> <a href="services_dnsmasq_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="services_dnsmasq.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this host?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="4"></td>
+                  <td class="list"> <a href="services_dnsmasq_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/services_dnsmasq_edit.php b/webgui/services_dnsmasq_edit.php
new file mode 100644 (file)
index 0000000..b48e22f
--- /dev/null
@@ -0,0 +1,161 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_dnsmasq_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Bob Zoller <bob@kludgebox.com> and Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['dnsmasq']['hosts'])) {
+       $config['dnsmasq']['hosts'] = array();
+}
+hosts_sort();
+$a_hosts = &$config['dnsmasq']['hosts'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_hosts[$id]) {
+       $pconfig['host'] = $a_hosts[$id]['host'];
+       $pconfig['domain'] = $a_hosts[$id]['domain'];
+       $pconfig['ip'] = $a_hosts[$id]['ip'];
+       $pconfig['descr'] = $a_hosts[$id]['descr'];
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "domain ip");
+       $reqdfieldsn = explode(",", "Domain,IP address");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['host'] && !is_hostname($_POST['host']))) {
+               $input_errors[] = "A valid host must be specified.";
+       }
+       if (($_POST['domain'] && !is_domain($_POST['domain']))) {
+               $input_errors[] = "A valid domain must be specified.";
+       }
+       if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
+               $input_errors[] = "A valid IP address must be specified.";
+       }
+
+       /* check for overlaps */
+       foreach ($a_hosts as $hostent) {
+               if (isset($id) && ($a_hosts[$id]) && ($a_hosts[$id] === $hostent))
+                       continue;
+
+               if (($hostent['host'] == $_POST['host']) && ($hostent['domain'] == $_POST['domain'])) {
+                       $input_errors[] = "This host/domain already exists.";
+                       break;
+               }
+       }
+
+       if (!$input_errors) {
+               $hostent = array();
+               $hostent['host'] = $_POST['host'];
+               $hostent['domain'] = $_POST['domain'];
+               $hostent['ip'] = $_POST['ip'];
+               $hostent['descr'] = $_POST['descr'];
+
+               if (isset($id) && $a_hosts[$id])
+                       $a_hosts[$id] = $hostent;
+               else
+                       $a_hosts[] = $hostent;
+               
+               touch($d_hostsdirty_path);
+               
+               write_config();
+               
+               header("Location: services_dnsmasq.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: DNS forwarder: Edit host</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DNS forwarder: Edit host</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="services_dnsmasq_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr>
+                  <td width="22%" valign="top" class="vncell">Host</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="host" type="text" class="formfld" id="host" size="40" value="<?=htmlspecialchars($pconfig['host']);?>">
+                    <br> <span class="vexpl">Name of the host, without
+                    domain part<br>
+                    e.g. <em>myhost</em></span></td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncellreq">Domain</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="domain" type="text" class="formfld" id="domain" size="40" value="<?=htmlspecialchars($pconfig['domain']);?>">
+                    <br> <span class="vexpl">Domain of the host<br>
+                    e.g. <em>blah.com</em></span></td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncellreq">IP address</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="ip" type="text" class="formfld" id="ip" size="40" value="<?=htmlspecialchars($pconfig['ip']);?>">
+                    <br> <span class="vexpl">IP address of the host<br>
+                    e.g. <em>192.168.100.100</em></span></td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+                    <br> <span class="vexpl">You may enter a description here
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr>
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save">
+                    <?php if (isset($id) && $a_hosts[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/services_dyndns.php b/webgui/services_dyndns.php
new file mode 100644 (file)
index 0000000..e12098b
--- /dev/null
@@ -0,0 +1,197 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_dyndns.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['username'] = $config['dyndns']['username'];
+$pconfig['password'] = $config['dyndns']['password'];
+$pconfig['host'] = $config['dyndns']['host'];
+$pconfig['mx'] = $config['dyndns']['mx'];
+$pconfig['type'] = $config['dyndns']['type'];
+$pconfig['enable'] = isset($config['dyndns']['enable']);
+$pconfig['wildcard'] = isset($config['dyndns']['wildcard']);
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['enable']) {
+               $reqdfields = explode(" ", "host username password type");
+               $reqdfieldsn = explode(",", "Hostname,Username,Password,Service type");
+               
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       }
+       
+       if (($_POST['host'] && !is_domain($_POST['host']))) {
+               $input_errors[] = "The host name contains invalid characters.";
+       }
+       if (($_POST['mx'] && !is_domain($_POST['mx']))) {
+               $input_errors[] = "The MX contains invalid characters.";
+       }
+       if (($_POST['username'] && !is_dyndns_username($_POST['username']))) {
+               $input_errors[] = "The username contains invalid characters.";
+       }
+
+       if (!$input_errors) {
+               $config['dyndns']['type'] = $_POST['type'];     
+               $config['dyndns']['username'] = $_POST['username'];
+               $config['dyndns']['password'] = $_POST['password'];
+               $config['dyndns']['host'] = $_POST['host'];
+               $config['dyndns']['mx'] = $_POST['mx'];
+               $config['dyndns']['wildcard'] = $_POST['wildcard'] ? true : false;
+               $config['dyndns']['enable'] = $_POST['enable'] ? true : false;
+                       
+               write_config();
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       /* nuke the cache file */
+                       config_lock();
+                       services_dyndns_reset();
+                       $retval = services_dyndns_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: Dynamic DNS client</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_change) {
+       if (document.iform.enable.checked || enable_change) {
+               document.iform.host.disabled = 0;
+               document.iform.mx.disabled = 0;
+               document.iform.type.disabled = 0;
+               document.iform.wildcard.disabled = 0;
+               document.iform.username.disabled = 0;
+               document.iform.password.disabled = 0;
+       } else {
+               document.iform.host.disabled = 1;
+               document.iform.mx.disabled = 1;
+               document.iform.type.disabled = 1;
+               document.iform.wildcard.disabled = 1;
+               document.iform.username.disabled = 1;
+               document.iform.password.disabled = 1;
+       }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Dynamic DNS client</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+            <form action="services_dyndns.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+                    <strong>Enable Dynamic DNS client</strong></td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Service type</td>
+                  <td width="78%" class="vtable">
+<select name="type" class="formfld" id="type">
+                      <?php $types = explode(",", "DynDNS,DHS,ODS,DyNS,HN.ORG,ZoneEdit,GNUDip,DynDNS (static),DynDNS (custom),easyDNS,EZ-IP,TZO");
+                                               $vals = explode(" ", "dyndns dhs ods dyns hn zoneedit gnudip dyndns-static dyndns-custom easydns ezip tzo");
+                                         $j = 0; for ($j = 0; $j < count($vals); $j++): ?>
+                      <option value="<?=$vals[$j];?>" <?php if ($vals[$j] == $pconfig['type']) echo "selected";?>> 
+                      <?=htmlspecialchars($types[$j]);?>
+                      </option>
+                      <?php endfor; ?>
+                    </select></td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Hostname</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="host" type="text" class="formfld" id="host" size="30" value="<?=htmlspecialchars($pconfig['host']);?>"> 
+                  </td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">MX</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="mx" type="text" class="formfld" id="mx" size="30" value="<?=htmlspecialchars($pconfig['mx']);?>"> 
+                    <br>
+                    Set this option only if you need a special MX record. Not 
+                    all services support this.</td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Wildcards</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="wildcard" type="checkbox" id="wildcard" value="yes" <?php if ($pconfig['wildcard'] == "yes") echo "checked"; ?>>
+                    Enable Wildcard</td>
+                               </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Username</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Password</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="password" type="password" class="formfld" id="password" size="20" value="<?=htmlspecialchars($pconfig['password']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+                    </strong></span>You must configure a DNS server in <a href="system.php">System: 
+                    General setup</a> or allow the DNS server list to be overridden 
+                    by DHCP/PPP on WAN for the DynDNS client to work.</span></td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/services_proxyarp.php b/webgui/services_proxyarp.php
new file mode 100644 (file)
index 0000000..9591063
--- /dev/null
@@ -0,0 +1,124 @@
+#!/usr/local/bin/php
+<?php
+/*
+       services_proxyarp.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['proxyarp']['proxyarpnet'])) {
+       $config['proxyarp']['proxyarpnet'] = array();
+}
+proxyarp_sort();
+$a_proxyarp = &$config['proxyarp']['proxyarpnet'];
+
+if ($_POST) {
+       $pconfig = $_POST;
+       
+       $retval = 0;
+       if (!file_exists($d_sysrebootreqd_path)) {
+               config_lock();
+               $retval = services_proxyarp_configure();
+               config_unlock();
+       }
+       $savemsg = get_std_save_message($retval);
+
+       if ($retval == 0) {
+               if (file_exists($d_proxyarpdirty_path))
+                       unlink($d_proxyarpdirty_path);
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_proxyarp[$_GET['id']]) {
+               unset($a_proxyarp[$_GET['id']]);
+               write_config();
+               touch($d_proxyarpdirty_path);
+               header("Location: services_proxyarp.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: Proxy ARP</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Proxy ARP</p>
+<form action="services_proxyarp.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_proxyarpdirty_path)): ?><p>
+<?php print_info_box_np("The proxy ARP configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td width="40%" class="listhdrr">Network</td>
+                  <td width="50%" class="listhdrr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_proxyarp as $arpent): ?>
+                <tr>
+                  <td class="listlr">
+                                 <?php if (isset($arpent['network'])) {
+                                                       list($sa,$sn) = explode("/", $arpent['network']);
+                                                       if ($sn == 32)
+                                                               echo $sa;
+                                                       else
+                                                               echo $arpent['network'];
+                                               } else if (isset($arpent['range']))
+                                                       echo $arpent['range']['from'] . "-" . $arpent['range']['to'];
+                    ?>&nbsp;
+                  </td>
+                  <td class="listbg">
+                    <?=htmlspecialchars($arpent['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" nowrap class="list"> <a href="services_proxyarp_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="services_proxyarp.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this network?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="2"></td>
+                  <td class="list"> <a href="services_proxyarp_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+            </form>
+            <p class="vexpl"><span class="red"><strong>Note:<br>
+                      </strong></span>Proxy ARP can be used if you need m0n0wall to send ARP
+                                         replies on the WAN interface for other IP addresses than its own WAN
+                                         IP address (e.g. for 1:1, advanced outbound or server NAT). It is not
+                                         necessary if you have a subnet routed to you or if you use PPPoE/PPTP, and it only works if
+                                         the WAN interface is configured with a static IP address or DHCP.</p>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/services_proxyarp_edit.php b/webgui/services_proxyarp_edit.php
new file mode 100644 (file)
index 0000000..a9ee249
--- /dev/null
@@ -0,0 +1,232 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_proxyarp_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['proxyarp']['proxyarpnet'])) {
+       $config['proxyarp']['proxyarpnet'] = array();
+}
+proxyarp_sort();
+$a_proxyarp = &$config['proxyarp']['proxyarpnet'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_proxyarp[$id]) {
+       if (isset($a_proxyarp[$id]['network']))
+               list($pconfig['subnet'], $pconfig['subnet_bits']) = explode("/", $a_proxyarp[$id]['network']);
+       else if (isset($a_proxyarp[$id]['range'])) {
+               $pconfig['range_from'] = $a_proxyarp[$id]['range']['from'];
+               $pconfig['range_to'] = $a_proxyarp[$id]['range']['to'];
+       }
+       $pconfig['descr'] = $a_proxyarp[$id]['descr'];
+} else {
+       $pconfig['subnet_bits'] = 32;
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['type'] == "single") {
+               $reqdfields = explode(" ", "subnet");
+               $reqdfieldsn = explode(",", "Address");
+               $_POST['subnet_bits'] = 32;
+       } else if ($_POST['type'] == "network") {
+               $reqdfields = explode(" ", "subnet subnet_bits");
+               $reqdfieldsn = explode(",", "Network,Network mask");
+       } else if ($_POST['type'] == "range") {
+               $reqdfields = explode(" ", "range_from range_to");
+               $reqdfieldsn = explode(",", "Range start,Range end");
+       }
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if ((($_POST['type'] != "range") && $_POST['subnet'] && !is_ipaddr($_POST['subnet']))) {
+               $input_errors[] = "A valid address must be specified.";
+       }
+       if ((($_POST['type'] == "range") && $_POST['range_from'] && !is_ipaddr($_POST['range_from']))) {
+               $input_errors[] = "A valid range start must be specified.";
+       }
+       if ((($_POST['type'] == "range") && $_POST['range_to'] && !is_ipaddr($_POST['range_to']))) {
+               $input_errors[] = "A valid range end must be specified.";
+       }
+
+       /* check for overlaps */
+       foreach ($a_proxyarp as $arpent) {
+               if (isset($id) && ($a_proxyarp[$id]) && ($a_proxyarp[$id] === $arpent))
+                       continue;
+               
+               if (($_POST['type'] == "range") && isset($arpent['range'])) {
+                       if (($_POST['range_from'] == $arpent['range']['from']) && 
+                               ($_POST['range_to'] == $arpent['range']['to'])) {
+                               $input_errors[] = "This range already exists.";
+                               break;
+                       }
+               } else if (isset($arpent['network'])) {
+                       if (($arpent['network'] == "{$_POST['subnet']}/{$_POST['subnet_bits']}")) {
+                               $input_errors[] = "This network already exists.";
+                               break;
+                       }
+               }
+       }
+
+       if (!$input_errors) {
+               $arpent = array();
+               if ($_POST['type'] == "range") {
+                       $arpent['range']['from'] = $_POST['range_from'];
+                       $arpent['range']['to'] = $_POST['range_to'];
+               } else
+                       $arpent['network'] = $_POST['subnet'] . "/" . $_POST['subnet_bits'];
+               $arpent['descr'] = $_POST['descr'];
+
+               if (isset($id) && $a_proxyarp[$id])
+                       $a_proxyarp[$id] = $arpent;
+               else
+                       $a_proxyarp[] = $arpent;
+               
+               touch($d_proxyarpdirty_path);
+               
+               write_config();
+               
+               header("Location: services_proxyarp.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: Proxy ARP: Edit</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+    switch (document.iform.type.selectedIndex) {
+        case 0: // single
+            document.iform.subnet.disabled = 0;
+            document.iform.subnet_bits.disabled = 1;
+            document.iform.range_from.disabled = 1;
+            document.iform.range_to.disabled = 1;
+            break;
+        case 1: // network
+            document.iform.subnet.disabled = 0;
+            document.iform.subnet_bits.disabled = 0;
+            document.iform.range_from.disabled = 1;
+            document.iform.range_to.disabled = 1;
+            break;
+        case 2: // range
+            document.iform.subnet.disabled = 1;
+            document.iform.subnet_bits.disabled = 1;
+            document.iform.range_from.disabled = 0;
+            document.iform.range_to.disabled = 0;
+            break;
+    }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Proxy ARP: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="services_proxyarp_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td valign="top" class="vncellreq">Network</td>
+                  <td class="vtable">
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>Type:&nbsp;&nbsp;</td>
+                        <td><select name="type" class="formfld" onChange="typesel_change()">
+                            <option value="single" <?php if (!$pconfig['range_from'] && $pconfig['subnet_bits'] == 32) echo "selected"; ?>> 
+                            Single address</option>
+                            <option value="network" <?php if (!$pconfig['range_from'] && $pconfig['subnet_bits'] != 32) echo "selected"; ?>> 
+                            Network</option>
+                            <option value="range" <?php if ($pconfig['range_from']) echo "selected"; ?>> 
+                            Range</option>
+                          </select></td>
+                      </tr>
+                      <tr> 
+                        <td>Address:&nbsp;&nbsp;</td>
+                        <td><input name="subnet" type="text" class="formfld" id="subnet" size="20" value="<?=htmlspecialchars($pconfig['subnet']);?>">
+                  / 
+                          <select name="subnet_bits" class="formfld" id="select">
+                            <?php for ($i = 31; $i >= 0; $i--): ?>
+                            <option value="<?=$i;?>" <?php if ($i == $pconfig['subnet_bits']) echo "selected"; ?>>
+                            <?=$i;?>
+                      </option>
+                            <?php endfor; ?>
+                      </select>
+ </td>
+                      </tr>
+                      <tr> 
+                        <td>Range:&nbsp;&nbsp;</td>
+                        <td><input name="range_from" type="text" class="formfld" id="range_from" size="20" value="<?=htmlspecialchars($pconfig['range_from']);?>">
+- 
+                          <input name="range_to" type="text" class="formfld" id="range_to" size="20" value="<?=htmlspecialchars($pconfig['range_to']);?>">                          
+                          </td>
+                      </tr>
+                    </table>
+                  </td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+                    <br> <span class="vexpl">You may enter a description here
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr>
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save">
+                    <?php if (isset($id) && $a_proxyarp[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/services_snmp.php b/webgui/services_snmp.php
new file mode 100644 (file)
index 0000000..7d02cfe
--- /dev/null
@@ -0,0 +1,145 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       services_snmp.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['snmpd'])) {
+       $config['snmpd'] = array();
+       $config['snmpd']['rocommunity'] = "public";
+}
+
+$pconfig['syslocation'] = $config['snmpd']['syslocation'];
+$pconfig['syscontact'] = $config['snmpd']['syscontact'];
+$pconfig['rocommunity'] = $config['snmpd']['rocommunity'];
+$pconfig['enable'] = isset($config['snmpd']['enable']);
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['enable']) {
+               $reqdfields = explode(" ", "rocommunity");
+               $reqdfieldsn = explode(",", "Community");
+               
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       }
+
+       if (!$input_errors) {
+               $config['snmpd']['syslocation'] = $_POST['syslocation'];        
+               $config['snmpd']['syscontact'] = $_POST['syscontact'];
+               $config['snmpd']['rocommunity'] = $_POST['rocommunity'];
+               $config['snmpd']['enable'] = $_POST['enable'] ? true : false;
+                       
+               write_config();
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = services_snmpd_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Services: SNMP</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_change) {
+       if (document.iform.enable.checked || enable_change) {
+               document.iform.syslocation.disabled = 0;
+               document.iform.syscontact.disabled = 0;
+               document.iform.rocommunity.disabled = 0;
+       } else {
+               document.iform.syslocation.disabled = 1;
+               document.iform.syscontact.disabled = 1;
+               document.iform.rocommunity.disabled = 1;
+       }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: SNMP</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+            <form action="services_snmp.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable">
+<input name="enable" type="checkbox" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?> onClick="enable_change(false)">
+                    <strong>Enable SNMP agent</strong></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">System location</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="syslocation" type="text" class="formfld" id="syslocation" size="40" value="<?=htmlspecialchars($pconfig['syslocation']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">System contact</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="syscontact" type="text" class="formfld" id="syscontact" size="40" value="<?=htmlspecialchars($pconfig['syscontact']);?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Community</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="rocommunity" type="text" class="formfld" id="rocommunity" size="40" value="<?=htmlspecialchars($pconfig['rocommunity']);?>"> 
+                    <br>
+                    In most cases, &quot;public&quot; is used here</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save" onClick="enable_change(true)"> 
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/status.php b/webgui/status.php
new file mode 100644 (file)
index 0000000..37558ac
--- /dev/null
@@ -0,0 +1,150 @@
+#!/usr/local/bin/php
+<?php
+/* Run various commands and collect their output into HTML tables.
+ * Jim McBeath <jimmc@macrovision.com> Nov 2003
+ *
+ * (modified for m0n0wall by Manuel Kasper <mk@neon1.net>)
+ */
+
+/* Execute a command, with a title, and generate an HTML table
+ * showing the results.
+ */
+function doCmdT($title, $command) {
+    echo "<p>\n";
+    echo "<a name=\"" . $title . "\">\n";
+    echo "<table border=\"0\" cellpadding=\"0\" cellspacing=\"0\">\n";
+    echo "<tr><td class=\"listtopic\">" . $title . "</td></tr>\n";
+    echo "<tr><td class=\"listlr\"><pre>";             /* no newline after pre */
+       
+       if ($command == "dumpconfigxml") {
+               $fd = @fopen("/conf/config.xml", "r");
+               if ($fd) {
+                       while (!feof($fd)) {
+                               $line = fgets($fd);
+                               /* remove password tag contents */
+                               $line = preg_replace("/<password>.*?<\\/password>/", "<password>xxxxx</password>", $line);
+                               $line = preg_replace("/<pre-shared-key>.*?<\\/pre-shared-key>/", "<pre-shared-key>xxxxx</pre-shared-key>", $line);
+                               $line = str_replace("\t", "    ", $line);
+                               echo htmlspecialchars($line,ENT_NOQUOTES);
+                       }
+               }
+               fclose($fd);
+       } else {
+               exec ($command . " 2>&1", $execOutput, $execStatus);
+               for ($i = 0; isset($execOutput[$i]); $i++) {
+                       if ($i > 0) {
+                               echo "\n";
+                       }
+                       echo htmlspecialchars($execOutput[$i],ENT_NOQUOTES);
+               }
+       }
+    echo "</pre></tr>\n";
+    echo "</table>\n";
+}
+
+/* Execute a command, giving it a title which is the same as the command. */
+function doCmd($command) {
+    doCmdT($command,$command);
+}
+
+/* Define a command, with a title, to be executed later. */
+function defCmdT($title, $command) {
+    global $commands;
+    $title = htmlspecialchars($title,ENT_NOQUOTES);
+    $commands[] = array($title, $command);
+}
+
+/* Define a command, with a title which is the same as the command,
+ * to be executed later.
+ */
+function defCmd($command) {
+    defCmdT($command,$command);
+}
+
+/* List all of the commands as an index. */
+function listCmds() {
+    global $commands;
+    echo "<p>This status page includes the following information:\n";
+    echo "<ul>\n";
+    for ($i = 0; isset($commands[$i]); $i++ ) {
+        echo "<li><strong><a href=\"#" . $commands[$i][0] . "\">" . $commands[$i][0] . "</a></strong>\n";
+    }
+    echo "</ul>\n";
+}
+
+/* Execute all of the commands which were defined by a call to defCmd. */
+function execCmds() {
+    global $commands;
+    for ($i = 0; isset($commands[$i]); $i++ ) {
+        doCmdT($commands[$i][0], $commands[$i][1]);
+    }
+}
+
+/* Set up all of the commands we want to execute. */
+defCmdT("System uptime","uptime");
+defCmdT("Interfaces","/sbin/ifconfig -a");
+
+defCmdT("Routing tables","netstat -nr");
+
+defCmdT("ipfw show", "/sbin/ipfw show");
+defCmdT("ipnat -lv", "/sbin/ipnat -lv");
+defCmdT("ipfstat -v", "/sbin/ipfstat -v");
+defCmdT("ipfstat -nio", "/sbin/ipfstat -nio");
+
+defCmdT("resolv.conf","cat /etc/resolv.conf");
+
+defCmdT("Processes","ps xauww");
+defCmdT("dhcpd.conf","cat /var/etc/dhcpd.conf");
+defCmdT("ez-ipupdate.cache","cat /conf/ez-ipupdate.cache");
+
+defCmdT("df","/bin/df");
+
+defCmdT("racoon.conf","cat /var/etc/racoon.conf");
+defCmdT("SPD","/usr/sbin/setkey -DP");
+defCmdT("SAD","/usr/sbin/setkey -D");
+
+defCmdT("last 200 system log entries","/usr/sbin/clog /var/log/system.log 2>&1 | tail -n 200");
+defCmdT("last 50 filter log entries","/usr/sbin/clog /var/log/filter.log 2>&1 | tail -n 50");
+
+defCmd("ls /conf");
+defCmd("ls /var/run");
+defCmdT("config.xml","dumpconfigxml");
+
+$pageTitle = "m0n0wall: status";
+
+exec("/bin/date", $dateOutput, $dateStatus);
+$currentDate = $dateOutput[0];
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=$pageTitle;?></title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<style type="text/css">
+<!--
+pre {
+   margin: 0px;
+   font-family: courier new, courier;
+   font-weight: normal;
+   font-size: 9pt;
+}
+-->
+</style>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<p><span class="pgtitle"><?=$pageTitle;?></span><br>
+<strong><?=$currentDate;?></strong>
+<p><span class="red"><strong>Note: make sure to remove any sensitive information 
+(passwords, maybe also IP addresses) before posting 
+information from this page in public places (like mailing lists)!</strong></span><br>
+Passwords in config.xml have been automatically removed.
+
+<?php listCmds(); ?>
+
+<?php execCmds(); ?>
+
+</body>
+</html>
diff --git a/webgui/status_interfaces.php b/webgui/status_interfaces.php
new file mode 100644 (file)
index 0000000..a7923ef
--- /dev/null
@@ -0,0 +1,228 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       status_interfaces.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+function get_interface_info($ifdescr) {
+       
+       global $config, $g;
+       
+       $ifinfo = array();
+       
+       /* find out interface name */
+       if ($ifdescr == "wan")
+               $ifinfo['if'] = get_real_wan_interface();
+       else
+               $ifinfo['if'] = $config['interfaces'][$ifdescr]['if'];
+       
+       /* run netstat to determine link info */
+       unset($linkinfo);
+       exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f link", $linkinfo);
+       $linkinfo = preg_split("/\s+/", $linkinfo[1]);
+       if (preg_match("/\*$/", $linkinfo[0])) {
+               $ifinfo['status'] = "down";
+       } else {
+               $ifinfo['status'] = "up";
+       }
+       
+       if ($ifinfo['if'] != $g['pppoe_interface']) {
+               $ifinfo['macaddr'] = $linkinfo[3];
+               $ifinfo['inpkts'] = $linkinfo[4];
+               $ifinfo['inbytes'] = $linkinfo[6];
+               $ifinfo['outpkts'] = $linkinfo[7];
+               $ifinfo['outbytes'] = $linkinfo[9];
+       } else {
+               $ifinfo['inpkts'] = $linkinfo[3];
+               $ifinfo['inbytes'] = $linkinfo[5];
+               $ifinfo['outpkts'] = $linkinfo[6];
+               $ifinfo['outbytes'] = $linkinfo[8];
+       }
+       
+       if ($ifinfo['status'] == "up") {
+               /* run netstat to determine inet info */
+               unset($inetinfo);
+               exec("/usr/bin/netstat -I " . $ifinfo['if'] . " -nWb -f inet", $inetinfo);
+               $inetinfo = preg_split("/\s+/", $inetinfo[1]);
+               
+               $ifinfo['ipaddr'] = $inetinfo[3];
+               
+               if ($ifdescr == "wan") {
+                       /* run netstat to determine the default gateway */
+                       unset($netstatrninfo);
+                       exec("/usr/bin/netstat -rnf inet", $netstatrninfo);
+                       
+                       foreach ($netstatrninfo as $nsr) {
+                               if (preg_match("/^default\s*(\S+)/", $nsr, $matches)) {
+                                       $ifinfo['gateway'] = $matches[1];
+                               }
+                       }
+               }
+               
+               /* try to determine netmask and media with ifconfig */
+               unset($ifconfiginfo);
+               exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+               
+               foreach ($ifconfiginfo as $ici) {
+                       if (preg_match("/netmask (\S+)/", $ici, $matches) && !$ifinfo['subnet']) {
+                               if (preg_match("/^0x/", $matches[1])) {
+                                       $ifinfo['subnet'] = long2ip(hexdec($matches[1]));
+                               }
+                       }
+                       if (!isset($config['interfaces'][$ifdescr]['wireless'])) {
+                               /* don't list media/speed for wireless cards, as it always
+                                  displays 2 Mbps even though clients can connect at 11 Mbps */
+                               if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
+                                       $ifinfo['media'] = $matches[1];
+                               }
+                       }
+                       if (preg_match("/status: (.*)$/", $ici, $matches)) {
+                               if ($matches[1] != "active")
+                                       $ifinfo['status'] = $matches[1];
+                       }
+                       if (preg_match("/channel (\S*)/", $ici, $matches)) {
+                               $ifinfo['channel'] = $matches[1];
+                       }
+                       if (preg_match("/ssid (\S*)/", $ici, $matches)) {
+                               $ifinfo['ssid'] = $matches[1];
+                       }
+               }
+               
+               /* PPPoE only: get media from underlying ethernet interface */
+               if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pppoe")) {
+                       unset($ifconfiginfo);
+                       exec("/sbin/ifconfig " . $config['interfaces']['wan']['if'], $ifconfiginfo);
+                       
+                       foreach ($ifconfiginfo as $ici) {
+                               if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
+                                       $ifinfo['media'] = $matches[1];
+                               } else if (preg_match("/ether (.*)/", $ici, $matches)) {
+                                       $ifinfo['macaddr'] = $matches[1];
+                               }
+                       }
+               }
+       }
+       
+       return $ifinfo;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Status: Interfaces</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+      <p class="pgtitle">Status: Interfaces</p>
+            <table width="100%" border="0" cellspacing="0" cellpadding="0">
+              <?php $i = 0; $ifdescrs = array('wan' => 'WAN', 'lan' => 'LAN');
+                                               
+                                       for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+                                               $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+                                       }
+                                       
+                             foreach ($ifdescrs as $ifdescr => $ifname): 
+                                 $ifinfo = get_interface_info($ifdescr);
+                                 ?>
+              <?php if ($i): ?>
+              <tr>
+                                 <td colspan="8" class="list" height="12"></td>
+                               </tr>
+                               <?php endif; ?>
+              <tr> 
+                <td colspan="2" class="listtopic"> 
+                  <?=htmlspecialchars($ifname);?>
+                  interface</td>
+              </tr>
+              <tr> 
+                <td width="22%" class="listhdrr">Status</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['status']);?>
+                </td>
+              </tr><?php if ($ifinfo['macaddr']): ?>
+              <tr> 
+                <td width="22%" class="listhdrr">MAC address</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['macaddr']);?>
+                </td>
+              </tr><?php endif; if ($ifinfo['status'] != "down"): ?>
+                         <?php if ($ifinfo['ipaddr']): ?>
+              <tr> 
+                <td width="22%" class="listhdrr">IP address</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['ipaddr']);?>
+                  &nbsp; </td>
+              </tr><?php endif; ?><?php if ($ifinfo['subnet']): ?>
+              <tr> 
+                <td width="22%" class="listhdrr">Subnet mask</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['subnet']);?>
+                </td>
+              </tr><?php endif; ?><?php if ($ifinfo['gateway']): ?>
+              <tr> 
+                <td width="22%" class="listhdrr">Gateway</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['gateway']);?>
+                </td>
+              </tr><?php endif; ?><?php if ($ifinfo['media']): ?>
+              <tr> 
+                <td width="22%" class="listhdrr">Media</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['media']);?>
+                </td>
+              </tr><?php endif; ?><?php if ($ifinfo['channel']): ?>
+              <tr> 
+                <td width="22%" class="listhdrr">Channel</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['channel']);?>
+                </td>
+              </tr><?php endif; ?><?php if ($ifinfo['ssid']): ?>
+              <tr> 
+                <td width="22%" class="listhdrr">SSID</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['ssid']);?>
+                </td>
+              </tr><?php endif; ?>
+              <tr> 
+                <td width="22%" class="listhdrr">In/out packets</td>
+                <td width="78%" class="listr"> 
+                  <?=htmlspecialchars($ifinfo['inpkts'] . "/" . $ifinfo['outpkts'] . " (" . 
+                                               format_bytes($ifinfo['inbytes']) . "/" . format_bytes($ifinfo['outbytes']) . ")");?>
+                </td>
+              </tr><?php endif; ?>
+              <?php $i++; endforeach; ?>
+            </table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/status_wireless.php b/webgui/status_wireless.php
new file mode 100644 (file)
index 0000000..b020cd0
--- /dev/null
@@ -0,0 +1,189 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       status_wireless.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+function get_wireless_info($ifdescr) {
+       
+       global $config, $g;
+       
+       $ifinfo = array();
+       $ifinfo['if'] = $config['interfaces'][$ifdescr]['if'];
+       
+       /* get signal strength cache */
+       exec("/usr/sbin/wicontrol -i " . $ifinfo['if'] . " -C", $sscache);
+       
+       $ifinfo['sscache'] = array();
+       foreach ($sscache as $ss) {
+               if ($ss) {
+                       $ssa = preg_split("/\s+/", $ss);
+                       $sscent = array();
+                       $sscent['mac'] = chop($ssa[1], ",");
+                       $sscent['ipaddr'] = chop($ssa[2], ",");
+                       $sscent['sig'] = chop($ssa[4], ",");
+                       $sscent['noise'] = chop($ssa[6], ",");
+                       $sscent['qual'] = chop($ssa[8], ",");
+                       $ifinfo['sscache'][] = $sscent;
+               }
+       }
+       
+       /* if in hostap mode: get associated stations */
+       if ($config['interfaces'][$ifdescr]['wireless']['mode'] == "hostap") {
+               exec("/usr/sbin/wicontrol -i " . $ifinfo['if'] . " -l", $aslist);
+               
+               $ifinfo['aslist'] = array();
+               array_shift($aslist);
+               foreach ($aslist as $as) {
+                       if ($as) {
+                               $asa = preg_split("/\s+/", $as);
+                               $aslent = array();
+                               $aslent['mac'] = $asa[0];
+                               $aslent['rates'] = substr($asa[4], strpos($asa[4], "<")+1,
+                                       strpos($asa[4], ">")-strpos($asa[4], "<")-1);
+                               $aslent['sig'] = substr($asa[5], strpos($asa[5], "=")+1);
+                               $ifinfo['aslist'][] = $aslent;
+                       }
+               }
+       }
+       
+       return $ifinfo;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - Status: Wireless</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+      <p class="pgtitle">Status: Wireless</p>
+              <?php $i = 0; $ifdescrs = array();
+                         
+                                       if (is_array($config['interfaces']['wan']['wireless']) &&
+                                                       strstr($config['interfaces']['wan']['if'], "wi"))
+                                                       $ifdescrs['wan'] = 'WAN';
+                                                       
+                                       if (is_array($config['interfaces']['lan']['wireless']) &&
+                                                       strstr($config['interfaces']['lan']['if'], "wi"))
+                                                       $ifdescrs['lan'] = 'LAN';
+                                       
+                                       for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+                                               if (is_array($config['interfaces']['opt' . $j]['wireless']) &&
+                                                       isset($config['interfaces']['opt' . $j]['enable']) &&
+                                                       strstr($config['interfaces']['opt' . $j]['if'], "wi"))
+                                                       $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+                                       }
+                                               
+                                       if (count($ifdescrs) > 0): ?>
+            <table width="100%" border="0" cellspacing="0" cellpadding="0">
+              <?php
+                             foreach ($ifdescrs as $ifdescr => $ifname): 
+                                 $ifinfo = get_wireless_info($ifdescr);
+                         ?>
+              <?php if ($i): ?>
+              <tr> 
+                <td colspan="8" class="list" height="12"></td>
+              </tr>
+              <?php endif; ?>
+              <tr> 
+                <td colspan="2" class="listtopic"> 
+                  <?=htmlspecialchars($ifname);?> interface</td>
+              </tr>
+              <tr> 
+                <td width="22%" valign="top" class="listhdrr">Signal strength 
+                  cache</td>
+                <td width="78%" class="listrpad"> 
+                  <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                    <tr> 
+                      <td width="30%" class="listhdrr">MAC address</td>
+                      <td width="25%" class="listhdrr">IP address</td>
+                      <td width="15%" class="listhdrr">Signal</td>
+                      <td width="15%" class="listhdrr">Noise</td>
+                      <td width="15%" class="listhdr">Quality</td>
+                    </tr>
+                    <?php foreach ($ifinfo['sscache'] as $ss): ?>
+                    <tr> 
+                      <td class="listlr"> 
+                        <?=htmlspecialchars($ss['mac']);?>
+                      </td>
+                      <td class="listr"> 
+                        <?=htmlspecialchars($ss['ipaddr']);?>
+                      </td>
+                      <td class="listr"> 
+                        <?=htmlspecialchars($ss['sig']);?>
+                      </td>
+                      <td class="listr"> 
+                        <?=htmlspecialchars($ss['noise']);?>
+                      </td>
+                      <td class="listr"> 
+                        <?=htmlspecialchars($ss['qual']);?>
+                      </td>
+                    </tr>
+                    <?php endforeach; ?>
+                  </table></td>
+              </tr><?php if ($ifinfo['aslist']): ?>
+              <tr> 
+                <td width="22%" valign="top" class="listhdrr">Associated stations 
+                </td>
+                <td width="78%" class="listrpad"> 
+                  <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                    <tr> 
+                      <td width="40%" class="listhdrr">MAC address</td>
+                      <td width="40%" class="listhdrr">TX rates</td>
+                      <td width="20%" class="listhdrr">Signal</td>
+                    </tr>
+                    <?php foreach ($ifinfo['aslist'] as $as): ?>
+                    <tr> 
+                      <td class="listlr"> 
+                        <?=htmlspecialchars($as['mac']);?>
+                      </td>
+                      <td class="listr"> 
+                        <?=htmlspecialchars($as['rates']);?>
+                      </td>
+                      <td class="listr"> 
+                        <?=htmlspecialchars($as['sig']);?>
+                      </td>
+                    </tr>
+                    <?php endforeach; ?>
+                  </table></td>
+              </tr><?php endif; ?>
+              <?php $i++; endforeach; ?>
+            </table>
+<?php else: ?>
+<p><strong>No supported wireless interfaces were found for status display.</strong></p>
+<?php endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/system.php b/webgui/system.php
new file mode 100644 (file)
index 0000000..faa9d60
--- /dev/null
@@ -0,0 +1,260 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       system.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['hostname'] = $config['system']['hostname'];
+$pconfig['domain'] = $config['system']['domain'];
+list($pconfig['dns1'],$pconfig['dns2']) = $config['system']['dnsserver'];
+$pconfig['dnsallowoverride'] = isset($config['system']['dnsallowoverride']);
+$pconfig['username'] = $config['system']['username'];
+if (!$pconfig['username'])
+       $pconfig['username'] = "admin";
+$pconfig['webguiproto'] = $config['system']['webgui']['protocol'];
+if (!$pconfig['webguiproto'])
+       $pconfig['webguiproto'] = "http";
+$pconfig['webguiport'] = $config['system']['webgui']['port'];
+$pconfig['timezone'] = $config['system']['timezone'];
+$pconfig['timeupdateinterval'] = $config['system']['time-update-interval'];
+$pconfig['timeservers'] = $config['system']['timeservers'];
+
+if (!isset($pconfig['timeupdateinterval']))
+       $pconfig['timeupdateinterval'] = 300;
+if (!$pconfig['timezone'])
+       $pconfig['timezone'] = "Etc/UTC";
+if (!$pconfig['timeservers'])
+       $pconfig['timeservers'] = "pool.ntp.org";
+       
+function is_timezone($elt) {
+       return !preg_match("/\/$/", $elt);
+}
+
+exec('/usr/bin/tar -tzf /usr/share/zoneinfo.tgz', $timezonelist);
+$timezonelist = array_filter($timezonelist, 'is_timezone');
+sort($timezonelist);
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = split(" ", "hostname domain username");
+       $reqdfieldsn = split(",", "Hostname,Domain,Username");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if ($_POST['hostname'] && !is_hostname($_POST['hostname'])) {
+               $input_errors[] = "The hostname may only contain the characters a-z, 0-9 and '-'.";
+       }
+       if ($_POST['domain'] && !is_domain($_POST['domain'])) {
+               $input_errors[] = "The domain may only contain the characters a-z, 0-9, '-' and '.'.";
+       }
+       if (($_POST['dns1'] && !is_ipaddr($_POST['dns1'])) || ($_POST['dns2'] && !is_ipaddr($_POST['dns2']))) {
+               $input_errors[] = "A valid IP address must be specified for the primary/secondary DNS server.";
+       }
+       if ($_POST['username'] && !preg_match("/^[a-zA-Z0-9]*$/", $_POST['username'])) {
+               $input_errors[] = "The username may only contain the characters a-z, A-Z and 0-9.";
+       }
+       if ($_POST['webguiport'] && (!is_numericint($_POST['webguiport']) || 
+                       ($_POST['webguiport'] < 1) || ($_POST['webguiport'] > 65535))) {
+               $input_errors[] = "A valid TCP/IP port must be specified for the webGUI port.";
+       }
+       if (($_POST['password']) && ($_POST['password'] != $_POST['password2'])) {
+               $input_errors[] = "The passwords do not match.";
+       }
+       
+       $t = (int)$_POST['timeupdateinterval'];
+       if (($t < 0) || (($t > 0) && ($t < 6)) || ($t > 1440)) {
+               $input_errors[] = "The time update interval must be either 0 (disabled) or between 6 and 1440.";
+       }
+       foreach (explode(' ', $_POST['timeservers']) as $ts) {
+               if (!is_domain($ts)) {
+                       $input_errors[] = "A NTP Time Server name may only contain the characters a-z, 0-9, '-' and '.'.";
+               }
+       }
+
+       if (!$input_errors) {
+               $config['system']['hostname'] = strtolower($_POST['hostname']);
+               $config['system']['domain'] = strtolower($_POST['domain']);
+               $oldwebguiproto = $config['system']['webgui']['protocol'];
+               $config['system']['username'] = $_POST['username'];
+               $config['system']['webgui']['protocol'] = $pconfig['webguiproto'];
+               $oldwebguiport = $config['system']['webgui']['port'];
+               $config['system']['webgui']['port'] = $pconfig['webguiport'];
+               $config['system']['timezone'] = $_POST['timezone'];
+               $config['system']['timeservers'] = strtolower($_POST['timeservers']);
+               $config['system']['time-update-interval'] = $_POST['timeupdateinterval'];
+               
+               unset($config['system']['dnsserver']);
+               if ($_POST['dns1'])
+                       $config['system']['dnsserver'][] = $_POST['dns1'];
+               if ($_POST['dns2'])
+                       $config['system']['dnsserver'][] = $_POST['dns2'];
+               
+               $config['system']['dnsallowoverride'] = $_POST['dnsallowoverride'] ? true : false;
+               
+               if ($_POST['password']) {
+                       $config['system']['password'] = crypt($_POST['password']);
+               }
+               
+               write_config();
+               
+               if (($oldwebguiproto != $config['system']['webgui']['protocol']) ||
+                       ($oldwebguiport != $config['system']['webgui']['port']))
+                       touch($d_sysrebootreqd_path);
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = system_hostname_configure();
+                       $retval |= system_hosts_generate();
+                       $retval |= system_resolvconf_generate();
+                       $retval |= system_password_configure();
+                       $retval |= services_dnsmasq_configure();
+                       $retval |= system_timezone_configure();
+                       $retval |= system_ntp_configure();
+                       config_unlock();
+               }
+               
+               $savemsg = get_std_save_message($retval);
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - System: General setup</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+      <p class="pgtitle">System: General setup</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<form action="system.php" method="post">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Hostname</td>
+                  <td width="78%" class="vtable"> <input name="hostname" type="text" class="formfld" id="hostname" size="40" value="<?=htmlspecialchars($pconfig['hostname']);?>"> 
+                    <br> <span class="vexpl">name of the firewall host, without 
+                    domain part<br>
+                    e.g. <em>firewall</em></span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Domain</td>
+                  <td width="78%" class="vtable"> <input name="domain" type="text" class="formfld" id="domain" size="40" value="<?=htmlspecialchars($pconfig['domain']);?>"> 
+                    <br> <span class="vexpl">e.g. <em>mycorp.com</em> </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">DNS servers</td>
+                  <td width="78%" class="vtable"> <p> 
+                      <input name="dns1" type="text" class="formfld" id="dns1" size="20" value="<?=htmlspecialchars($pconfig['dns1']);?>">
+                      <br>
+                      <input name="dns2" type="text" class="formfld" id="dns22" size="20" value="<?=htmlspecialchars($pconfig['dns2']);?>">
+                      <br>
+                      <span class="vexpl">IP addresses; these are also used for 
+                      the DHCP service, DNS forwarder and for PPTP VPN clients<br>
+                      <br>
+                      <input name="dnsallowoverride" type="checkbox" id="dnsallowoverride" value="yes" <?php if ($pconfig['dnsallowoverride'] == "yes") echo "checked"; ?>>
+                      <strong>Allow DNS server list to be overridden by DHCP 
+                      on WAN</strong><br>
+                      If this option is set, m0n0wall will use DNS servers assigned 
+                      by a DHCP server on WAN for its own purposes (including 
+                      the DNS forwarder). They will not be assigned to DHCP and 
+                      PPTP VPN clients, though.</span></p></td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">Username</td>
+                  <td class="vtable"> <input name="username" type="text" class="formfld" id="username" size="20" value="<?=$pconfig['username'];?>">
+                    <br>
+                     <span class="vexpl">If you want 
+                    to change the username for accessing the webGUI, enter it 
+                    here.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Password</td>
+                  <td width="78%" class="vtable"> <input name="password" type="password" class="formfld" id="password" size="20"> 
+                    <br> <input name="password2" type="password" class="formfld" id="password2" size="20"> 
+                    &nbsp;(confirmation) <br> <span class="vexpl">If you want 
+                    to change the password for accessing the webGUI, enter it 
+                    here twice.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">webGUI protocol</td>
+                  <td width="78%" class="vtable"> <input name="webguiproto" type="radio" value="http" <?php if ($pconfig['webguiproto'] == "http") echo "checked"; ?>>
+                    HTTP &nbsp;&nbsp;&nbsp; <input type="radio" name="webguiproto" value="https" <?php if ($pconfig['webguiproto'] == "https") echo "checked"; ?>>
+                    HTTPS</td>
+                </tr>
+                <tr> 
+                  <td valign="top" class="vncell">webGUI port</td>
+                  <td class="vtable"> <input name="webguiport" type="text" class="formfld" id="webguiport" size="5" value="<?=htmlspecialchars($pconfig['webguiport']);?>"> 
+                    <br>
+                    <span class="vexpl">Enter a custom port number for the webGUI 
+                    above if you want to override the default (80 for HTTP, 443 
+                    for HTTPS).</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Time zone</td>
+                  <td width="78%" class="vtable"> <select name="timezone" id="timezone">
+                      <?php foreach ($timezonelist as $value): ?>
+                      <option value="<?=htmlspecialchars($value);?>" <?php if ($value == $pconfig['timezone']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($value);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Select the location closest 
+                    to you</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Time update interval</td>
+                  <td width="78%" class="vtable"> <input name="timeupdateinterval" type="text" class="formfld" id="timeupdateinterval" size="4" value="<?=htmlspecialchars($pconfig['timeupdateinterval']);?>"> 
+                    <br> <span class="vexpl">Minutes between network time sync.; 
+                    300 recommended, or 0 to disable </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">NTP time server</td>
+                  <td width="78%" class="vtable"> <input name="timeservers" type="text" class="formfld" id="timeservers" size="40" value="<?=htmlspecialchars($pconfig['timeservers']);?>"> 
+                    <br> <span class="vexpl">Use a space to separate multiple 
+                    hosts (only one required). Remember to set up at least one 
+                    DNS server if you enter a host name here!</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/system_advanced.php b/webgui/system_advanced.php
new file mode 100644 (file)
index 0000000..c0dde29
--- /dev/null
@@ -0,0 +1,211 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       system_advanced.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+$pconfig['filteringbridge_enable'] = isset($config['bridge']['filteringbridge']);
+$pconfig['ipv6nat_enable'] = isset($config['diag']['ipv6nat']['enable']);
+$pconfig['ipv6nat_ipaddr'] = $config['diag']['ipv6nat']['ipaddr'];
+$pconfig['cert'] = base64_decode($config['system']['webgui']['certificate']);
+$pconfig['key'] = base64_decode($config['system']['webgui']['private-key']);
+$pconfig['disableconsolemenu'] = isset($config['system']['disableconsolemenu']);
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */  
+       if ($_POST['ipv6nat_enable'] && !is_ipaddr($_POST['ipv6nat_ipaddr'])) {
+               $input_errors[] = "You must specify an IP address to NAT IPv6 packets.";
+       }       
+       if (($_POST['cert'] && !$_POST['key']) || ($_POST['key'] && !$_POST['cert'])) {
+               $input_errors[] = "Certificate and key must always be specified together.";
+       } else if ($_POST['cert'] && $_POST['key']) {
+               if (!strstr($_POST['cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cert'], "END CERTIFICATE"))
+                       $input_errors[] = "This certificate does not appear to be valid.";
+               if (!strstr($_POST['key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['key'], "END RSA PRIVATE KEY"))
+                       $input_errors[] = "This key does not appear to be valid.";
+       }
+
+       if (!$input_errors) {
+               $config['bridge']['filteringbridge'] = $_POST['filteringbridge_enable'] ? true : false;
+               $config['diag']['ipv6nat']['enable'] = $_POST['ipv6nat_enable'] ? true : false;
+               $config['diag']['ipv6nat']['ipaddr'] = $_POST['ipv6nat_ipaddr'];
+               $oldcert = $config['system']['webgui']['certificate'];
+               $oldkey = $config['system']['webgui']['private-key'];
+               $config['system']['webgui']['certificate'] = base64_encode($_POST['cert']);
+               $config['system']['webgui']['private-key'] = base64_encode($_POST['key']);
+               $config['system']['disableconsolemenu'] = $_POST['disableconsolemenu'] ? true : false;
+                       
+               write_config();
+               
+               if (($config['system']['webgui']['certificate'] != $oldcert)
+                               || ($config['system']['webgui']['private-key'] != $oldkey)) {
+                       touch($d_sysrebootreqd_path);
+               }
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = filter_configure();
+                       $retval = interfaces_optional_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - System: Advanced functions</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function enable_change(enable_over) {
+       if (document.iform.ipv6nat_enable.checked || enable_over) {
+               document.iform.ipv6nat_ipaddr.disabled = 0;
+       } else {
+               document.iform.ipv6nat_ipaddr.disabled = 1;
+       }
+}
+// -->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+      <p class="pgtitle">System: Advanced functions</p>
+            <?php if ($input_errors) print_input_errors($input_errors); ?>
+            <?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+            <p><span class="vexpl"><span class="red"><strong>Note: </strong></span>the 
+              options on this page are intended for use by advanced users only, 
+              and there's <strong>NO</strong> support for them.</span></p>
+            <form action="system_advanced.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td colspan="2" valign="top" class="listtopic">IPv6 tunneling</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="ipv6nat_enable" type="checkbox" id="ipv6nat_enable" value="yes" <?php if ($pconfig['ipv6nat_enable']) echo "checked"; ?> onclick="enable_change(false)"> 
+                    <strong>NAT encapsulated IPv6 packets (IP protocol 41/RFC2893) 
+                    to:</strong><br> <br> <input name="ipv6nat_ipaddr" type="text" class="formfld" id="ipv6nat_ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipv6nat_ipaddr']);?>"> 
+                    &nbsp;(IP address)<span class="vexpl"><br>
+                    Don't forget to add a firewall rule to permit IPv6 packets!</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td colspan="2" class="list" height="12"></td>
+                </tr>
+                               <tr> 
+                  <td colspan="2" valign="top" class="listtopic">Filtering bridge</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="filteringbridge_enable" type="checkbox" id="filteringbridge_enable" value="yes" <?php if ($pconfig['filteringbridge_enable']) echo "checked"; ?>>
+                    <strong>Enable filtering bridge</strong><span class="vexpl"><br>
+                    This will cause bridged packets to pass through the packet 
+                    filter in the same way as routed packets do (by default bridged 
+                    packets are always passed). If you enable this option, you'll 
+                    have to add filter rules to selectively permit traffic from 
+                    bridged interfaces.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td colspan="2" class="list" height="12"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="listtopic">webGUI SSL certificate/key</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Certificate</td>
+                  <td width="78%" class="vtable"> 
+                    <textarea name="cert" cols="65" rows="7" id="cert" class="formpre"><?=htmlspecialchars($pconfig['cert']);?></textarea>
+                    <br> 
+                    Paste a signed certificate in X.509 PEM format here.</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Key</td>
+                  <td width="78%" class="vtable"> 
+                    <textarea name="key" cols="65" rows="7" id="key" class="formpre"><?=htmlspecialchars($pconfig['key']);?></textarea>
+                    <br> 
+                    Paste an RSA private key in PEM format here.</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td colspan="2" class="list" height="12"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="listtopic">Miscellaneous</td>
+                </tr>
+                               <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="disableconsolemenu" type="checkbox" id="disableconsolemenu" value="yes" <?php if ($pconfig['disableconsolemenu']) echo "checked"; ?>>
+                    <strong>Disable console menu</strong><span class="vexpl"><br>
+                    Changes to this option will take effect after a reboot.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                  </td>
+                </tr>
+              </table>
+</form>
+            <script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/system_firmware.php b/webgui/system_firmware.php
new file mode 100644 (file)
index 0000000..421b62b
--- /dev/null
@@ -0,0 +1,199 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       system_firmware.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+$d_isfwfile = 1; require("guiconfig.inc"); 
+
+/* checks with m0n0.ch to see if a newer firmware version is available;
+   returns any HTML message it gets from the server */
+function check_firmware_version() {
+       global $g;
+       $post = "platform=" . rawurlencode($g['platform']) . 
+               "&version=" . rawurlencode(trim(file_get_contents("/etc/version")));
+               
+       $rfd = @fsockopen("m0n0.ch", 80, $errno, $errstr, 3);
+       if ($rfd) {
+               $hdr = "POST /wall/checkversion.php HTTP/1.0\r\n";
+               $hdr .= "Content-Type: application/x-www-form-urlencoded\r\n";
+               $hdr .= "User-Agent: m0n0wall-webGUI/1.0\r\n";
+               $hdr .= "Host: m0n0.ch\r\n";
+               $hdr .= "Content-Length: " . strlen($post) . "\r\n\r\n";
+               
+               fwrite($rfd, $hdr);
+               fwrite($rfd, $post);
+               
+               $inhdr = true;
+               $resp = "";
+               while (!feof($rfd)) {
+                       $line = fgets($rfd);
+                       if ($inhdr) {
+                               if (trim($line) == "")
+                                       $inhdr = false;
+                       } else {
+                               $resp .= $line;
+                       }
+               }
+               
+               fclose($rfd);
+               
+               return $resp;
+       }
+       
+       return null;
+}
+
+if ($_POST && !file_exists($d_firmwarelock_path)) {
+
+       unset($input_errors);
+       unset($sig_warning);
+       
+       if (stristr($_POST['Submit'], "Enable"))
+               $mode = "enable";
+       else if (stristr($_POST['Submit'], "Disable"))
+               $mode = "disable";
+       else if (stristr($_POST['Submit'], "Upgrade") || $_POST['sig_override'])
+               $mode = "upgrade";
+       else if ($_POST['sig_no'])
+               unlink("{$g['ftmp_path']}/firmware.img");
+               
+       if ($mode) {
+               if ($mode == "enable") {
+                       exec_rc_script("/etc/rc.firmware enable");
+                       touch($d_fwupenabled_path);
+               } else if ($mode == "disable") {
+                       exec_rc_script("/etc/rc.firmware disable");
+                       if (file_exists($d_fwupenabled_path))
+                               unlink($d_fwupenabled_path);
+               } else if ($mode == "upgrade") {
+                       if (is_uploaded_file($_FILES['ulfile']['tmp_name'])) {
+                               /* verify firmware image(s) */
+                               if (!stristr($_FILES['ulfile']['name'], $g['platform']) && !$_POST['sig_override'])
+                                       $input_errors[] = "The uploaded image file is not for this platfom ({$g['platform']}).";
+                               else {
+                                       /* move the image so PHP won't delete it */
+                                       rename($_FILES['ulfile']['tmp_name'], "{$g['ftmp_path']}/firmware.img");
+                                       
+                                       /* check digital signature */
+                                       $sigchk = verify_digital_signature("{$g['ftmp_path']}/firmware.img");
+                                       
+                                       if ($sigchk == 1)
+                                               $sig_warning = "The digital signature on this image is invalid.";
+                                       else if ($sigchk == 2)
+                                               $sig_warning = "This image is not digitally signed.";
+                                       else if (($sigchk == 3) || ($sigchk == 4))
+                                               $sig_warning = "There has been an error verifying the signature on this image.";
+                               
+                                       if (!verify_gzip_file("{$g['ftmp_path']}/firmware.img")) {
+                                               $input_errors[] = "The image file is corrupt.";
+                                               unlink("{$g['ftmp_path']}/firmware.img");
+                                       }
+                               }
+                       }
+
+                       if (!$input_errors && !file_exists($d_firmwarelock_path) && (!$sig_warning || $_POST['sig_override'])) {                        
+                               /* fire up the update script in the background */
+                               touch($d_firmwarelock_path);
+                               exec_rc_script_async("/etc/rc.firmware upgrade {$g['ftmp_path']}/firmware.img");
+                               
+                               $savemsg = "The firmware is now being installed. The firewall will reboot automatically.";
+                       }
+               }
+       }
+} else {
+       $fwinfo = check_firmware_version();
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - System: Firmware</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">System: Firmware</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if ($fwinfo) echo $fwinfo; ?>
+<?php if (!in_array($g['platform'], $fwupplatforms)): ?>
+<p><strong>Firmware uploading is not supported on this platform.</strong></p>
+<?php elseif ($sig_warning && !$input_errors): ?>
+<form action="system_firmware.php" method="post">
+<?php 
+$sig_warning = "<strong>" . $sig_warning . "</strong><br>This means that the image you uploaded " .
+       "is not an official supported image and may lead to unexpected behavior or security " .
+       "compromises. Only install images that come from sources that you trust, and make sure ".
+       "that the image has not been tampered with.<br><br>".
+       "Do you want to install this image anyway (on your own risk)?";
+print_info_box($sig_warning);
+?>
+<input name="sig_override" type="submit" class="formbtn" id="sig_override" value=" Yes ">
+<input name="sig_no" type="submit" class="formbtn" id="sig_no" value=" No ">
+</form>
+<?php else: ?>
+            <?php if (!file_exists($d_firmwarelock_path)): ?>
+            <p>Click &quot;Enable firmware 
+              upload&quot; below, then choose the image file (<?=$g['platform'];?>-*.img)
+                         to be uploaded.<br>Click &quot;Upgrade firmware&quot; 
+              to start the upgrade process.</p>
+            <form action="system_firmware.php" method="post" enctype="multipart/form-data">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <?php if (!file_exists($d_sysrebootreqd_path)): ?>
+                    <?php if (!file_exists($d_fwupenabled_path)): ?>
+                    <input name="Submit" type="submit" class="formbtn" value="Enable firmware upload">
+                                 <?php else: ?>
+                                  <input name="Submit" type="submit" class="formbtn" value="Disable firmware upload">
+                    <br><br>
+                                       <strong>Firmware image file: </strong>&nbsp;<input name="ulfile" type="file" class="formfld">
+                    <br><br>
+                    <input name="Submit" type="submit" class="formbtn" value="Upgrade firmware">
+                                 <?php endif; else: ?>
+                                   <strong>You must reboot the system before you can upgrade the firmware.</strong>
+                                 <?php endif; ?>
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"><span class="vexpl"><span class="red"><strong>Warning:<br>
+                    </strong></span>DO NOT abort the firmware upgrade once it 
+                    has started. The firewall will reboot automatically after 
+                    storing the new firmware. The configuration will be maintained.</span></td>
+                </tr>
+              </table>
+</form>
+<?php endif; endif; ?>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/system_routes.php b/webgui/system_routes.php
new file mode 100644 (file)
index 0000000..b63b410
--- /dev/null
@@ -0,0 +1,126 @@
+#!/usr/local/bin/php
+<?php
+/*
+       system_routes.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['staticroutes']['route']))
+       $config['staticroutes']['route'] = array();
+
+staticroutes_sort();
+$a_routes = &$config['staticroutes']['route'];
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       $retval = system_routing_configure();
+                       $retval |= filter_configure();
+               }
+               $savemsg = get_std_save_message($retval);
+               if ($retval == 0) {
+                       if (file_exists($d_staticroutesdirty_path)) {
+                               config_lock();
+                               unlink($d_staticroutesdirty_path);
+                               config_unlock();
+                       }
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_routes[$_GET['id']]) {
+               unset($a_routes[$_GET['id']]);
+               write_config();
+               touch($d_staticroutesdirty_path);
+               header("Location: system_routes.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - System: Static routes</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">System: Static routes</p>
+<form action="system_routes.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_staticroutesdirty_path)): ?><p>
+<?php print_info_box_np("The static route configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td width="15%" class="listhdrr">Interface</td>
+                  <td width="25%" class="listhdrr">Network</td>
+                  <td width="20%" class="listhdrr">Gateway</td>
+                  <td width="30%" class="listhdr">Description</td>
+                  <td width="10%" class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_routes as $route): ?>
+                <tr>
+                  <td class="listlr">
+                    <?php
+                                 $iflabels = array('lan' => 'LAN', 'pptp' => 'PPTP');
+                                 for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+                                       $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+                                 echo htmlspecialchars($iflabels[$route['interface']]); ?>
+                  </td>
+                  <td class="listr">
+                    <?=strtolower($route['network']);?>
+                  </td>
+                  <td class="listr">
+                    <?=strtolower($route['gateway']);?>
+                  </td>
+                  <td class="listbg">
+                    <?=htmlspecialchars($route['descr']);?>&nbsp;
+                  </td>
+                  <td valign="middle" nowrap class="list"> <a href="system_routes_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="system_routes.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this route?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="4"></td>
+                  <td class="list"> <a href="system_routes_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/system_routes_edit.php b/webgui/system_routes_edit.php
new file mode 100644 (file)
index 0000000..a267dbe
--- /dev/null
@@ -0,0 +1,177 @@
+#!/usr/local/bin/php
+<?php 
+/*
+       system_routes_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['staticroutes']['route']))
+       $config['staticroutes']['route'] = array();
+
+staticroutes_sort();
+$a_routes = &$config['staticroutes']['route'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_routes[$id]) {
+       $pconfig['interface'] = $a_routes[$id]['interface'];
+       list($pconfig['network'],$pconfig['network_subnet']) = 
+               explode('/', $a_routes[$id]['network']);
+       $pconfig['gateway'] = $a_routes[$id]['gateway'];
+       $pconfig['descr'] = $a_routes[$id]['descr'];
+}
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "interface network network_subnet gateway");
+       $reqdfieldsn = explode(",", "Interface,Destination network,Destination network bit count,Gateway");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['network'] && !is_ipaddr($_POST['network']))) {
+               $input_errors[] = "A valid destination network must be specified.";
+       }
+       if (($_POST['network_subnet'] && !is_numeric($_POST['network_subnet']))) {
+               $input_errors[] = "A valid destination network bit count must be specified.";
+       }
+       if (($_POST['gateway'] && !is_ipaddr($_POST['gateway']))) {
+               $input_errors[] = "A valid gateway IP address must be specified.";
+       }
+
+       /* check for overlaps */
+       $osn = gen_subnet($_POST['network'], $_POST['network_subnet']) . "/" . $_POST['network_subnet'];
+       foreach ($a_routes as $route) {
+               if (isset($id) && ($a_routes[$id]) && ($a_routes[$id] === $route))
+                       continue;
+
+               if ($route['network'] == $osn) {
+                       $input_errors[] = "A route to this destination network already exists.";
+                       break;
+               }
+       }
+
+       if (!$input_errors) {
+               $route = array();
+               $route['interface'] = $_POST['interface'];
+               $route['network'] = $osn;
+               $route['gateway'] = $_POST['gateway'];
+               $route['descr'] = $_POST['descr'];
+
+               if (isset($id) && $a_routes[$id])
+                       $a_routes[$id] = $route;
+               else
+                       $a_routes[] = $route;
+               
+               touch($d_staticroutesdirty_path);
+               
+               write_config();
+               
+               header("Location: system_routes.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - System: Static routes: Edit route</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">System: Static routes: Edit route</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="system_routes_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Interface</td>
+                  <td width="78%" class="vtable">
+<select name="interface" class="formfld">
+                      <?php $interfaces = array('lan' => 'LAN', 'pptp' => 'PPTP');
+                                         for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                                               $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+                                         }
+                                         foreach ($interfaces as $iface => $ifacename): ?>
+                      <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($ifacename);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Choose which interface this route applies to.</span></td>
+                </tr>
+                <tr>
+                  <td width="22%" valign="top" class="vncellreq">Destination network</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="network" type="text" class="formfld" id="network" size="20" value="<?=htmlspecialchars($pconfig['network']);?>"> 
+                                 / 
+                    <select name="network_subnet" class="formfld" id="network_subnet">
+                      <?php for ($i = 32; $i >= 1; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['network_subnet']) echo "selected"; ?>>
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select>
+                    <br> <span class="vexpl">Destination network for this static route</span></td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncellreq">Gateway</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="gateway" type="text" class="formfld" id="gateway" size="40" value="<?=htmlspecialchars($pconfig['gateway']);?>">
+                    <br> <span class="vexpl">Gateway to be used to reach the destination network</span></td>
+                </tr>
+                               <tr>
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>">
+                    <br> <span class="vexpl">You may enter a description here
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr>
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save">
+                    <?php if (isset($id) && $a_routes[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/tri_c.gif b/webgui/tri_c.gif
new file mode 100644 (file)
index 0000000..317b758
Binary files /dev/null and b/webgui/tri_c.gif differ
diff --git a/webgui/tri_o.gif b/webgui/tri_o.gif
new file mode 100644 (file)
index 0000000..eb95c32
Binary files /dev/null and b/webgui/tri_o.gif differ
diff --git a/webgui/up.gif b/webgui/up.gif
new file mode 100644 (file)
index 0000000..3db680a
Binary files /dev/null and b/webgui/up.gif differ
diff --git a/webgui/up_d.gif b/webgui/up_d.gif
new file mode 100644 (file)
index 0000000..5918e70
Binary files /dev/null and b/webgui/up_d.gif differ
diff --git a/webgui/vpn_ipsec.php b/webgui/vpn_ipsec.php
new file mode 100644 (file)
index 0000000..255454e
--- /dev/null
@@ -0,0 +1,191 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_ipsec.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['tunnel'])) {
+       $config['ipsec']['tunnel'] = array();
+}
+$a_ipsec = &$config['ipsec']['tunnel'];
+$wancfg = &$config['interfaces']['wan'];
+
+$pconfig['enable'] = isset($config['ipsec']['enable']);
+
+if ($_POST) {
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path))
+                       $retval = vpn_ipsec_configure();
+               $savemsg = get_std_save_message($retval);
+               if ($retval == 0) {
+                       if (file_exists($d_ipsecconfdirty_path))
+                               unlink($d_ipsecconfdirty_path);
+               }
+       } else if ($_POST['submit']) {
+               $pconfig = $_POST;
+               
+               $config['ipsec']['enable'] = $_POST['enable'] ? true : false;
+               
+               write_config();
+       
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = vpn_ipsec_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               if ($retval == 0) {
+                       if (file_exists($d_ipsecconfdirty_path))
+                               unlink($d_ipsecconfdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_ipsec[$_GET['id']]) {
+               unset($a_ipsec[$_GET['id']]);
+               write_config();
+               touch($d_ipsecconfdirty_path);
+               header("Location: vpn_ipsec.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: IPsec</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec</p>
+<form action="vpn_ipsec.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_ipsecconfdirty_path)): ?><p>
+<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabact">Tunnels</td>
+    <td nowrap class="tabinact"><a href="vpn_ipsec_mobile.php" class="tblnk">Mobile clients</a></td>
+    <td nowrap class="tabinact"><a href="vpn_ipsec_keys.php" class="tblnk">Pre-shared keys</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="4" class="tabcont">
+                       <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td class="vtable"><p><span class="vexpl"> </span> 
+                      <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable'] == "yes") echo "checked";?>>
+                      <strong>Enable IPsec<br>
+                      </strong></p></td>
+                </tr>
+                <tr> 
+                  <td> <input name="submit" type="submit" class="formbtn" value="Save"> 
+                  </td>
+                </tr>
+              </table>
+              &nbsp;<br>
+              <table width="100%" border="0" cellpadding="0" cellspacing="0">
+                <tr>
+                  <td nowrap class="listhdrr">Local net<br>
+                    Remote net</td>
+                  <td class="listhdrr">Interface<br>Remote gw</td>
+                  <td class="listhdrr">P1 mode</td>
+                  <td class="listhdrr">P1 Enc. Algo</td>
+                  <td class="listhdrr">P1 Hash Algo</td>
+                  <td class="listhdr">Description</td>
+                  <td class="list"></td>
+                               </tr>
+                <?php $i = 0; foreach ($a_ipsec as $ipsecent):
+                                       if (isset($ipsecent['disabled'])) {
+                                               $spans = "<span class=\"gray\">";
+                                               $spane = "</span>";
+                                       } else {
+                                               $spans = $spane = "";
+                                       }
+                               ?>
+                <tr valign="top">
+                  <td nowrap class="listlr"><?=$spans;?> 
+                    <?php      if ($ipsecent['local-subnet']['network'])
+                                                               echo strtoupper($ipsecent['local-subnet']['network']);
+                                                       else
+                                                               echo $ipsecent['local-subnet']['address'];
+                                       ?>
+                    <br>
+                    <?=$ipsecent['remote-subnet'];?>
+                  <?=$spane;?></td>
+                  <td class="listr"><?=$spans;?>
+                                 <?php if ($ipsecent['interface']) {
+                                                       $iflabels = array('lan' => 'LAN', 'wan' => 'WAN');
+                                                         for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++)
+                                                               $iflabels['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+                                                         $if = htmlspecialchars($iflabels[$ipsecent['interface']]);
+                                               } else
+                                                       $if = "WAN";
+                                               
+                                               echo $if . "<br>" . $ipsecent['remote-gateway'];
+                                       ?>
+                  <?=$spane;?></td>
+                  <td class="listr"><?=$spans;?>
+                                   <?=$ipsecent['p1']['mode'];?>
+                  <?=$spane;?></td>
+                  <td class="listr"><?=$spans;?>
+                                   <?=$p1_ealgos[$ipsecent['p1']['encryption-algorithm']];?>
+                  <?=$spane;?></td>
+                  <td class="listr"><?=$spans;?>
+                                   <?=$p1_halgos[$ipsecent['p1']['hash-algorithm']];?>
+                  <?=$spane;?></td>
+                  <td class="listbg"><?=$spans;?>
+                    <?=htmlspecialchars($ipsecent['descr']);?>&nbsp;
+                  <?=$spane;?></td>
+                  <td valign="middle" nowrap class="list"> <a href="vpn_ipsec_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a> 
+                    &nbsp;<a href="vpn_ipsec.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this tunnel?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="6"></td>
+                  <td class="list"> <a href="vpn_ipsec_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+                       </td>
+       </tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/vpn_ipsec_edit.php b/webgui/vpn_ipsec_edit.php
new file mode 100644 (file)
index 0000000..b6a13c0
--- /dev/null
@@ -0,0 +1,509 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_ipsec_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['tunnel'])) {
+       $config['ipsec']['tunnel'] = array();
+}
+$a_ipsec = &$config['ipsec']['tunnel'];
+
+$specialsrcdst = explode(" ", "lan");
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+       
+function is_specialnet($net) {
+       global $specialsrcdst;
+       
+       if (in_array($net, $specialsrcdst))
+               return true;
+       else
+               return false;
+}
+
+function address_to_pconfig($adr, &$padr, &$pmask) {
+               
+       if ($adr['network'])
+               $padr = $adr['network'];
+       else if ($adr['address']) {
+               list($padr, $pmask) = explode("/", $adr['address']);
+               if (!$pmask)
+                       $pmask = 32;
+       }
+}
+
+function pconfig_to_address(&$adr, $padr, $pmask) {
+       
+       $adr = array();
+       
+       if (is_specialnet($padr))
+               $adr['network'] = $padr;
+       else {
+               $adr['address'] = $padr;
+               if ($pmask != 32)
+                       $adr['address'] .= "/" . $pmask;
+       }
+}
+
+if (isset($id) && $a_ipsec[$id]) {
+       $pconfig['disabled'] = isset($a_ipsec[$id]['disabled']);
+
+       if (!isset($a_ipsec[$id]['local-subnet']))
+               $pconfig['localnet'] = "lan";
+       else
+               address_to_pconfig($a_ipsec[$id]['local-subnet'], $pconfig['localnet'], $pconfig['localnetmask']);
+               
+       if ($a_ipsec[$id]['interface'])
+               $pconfig['interface'] = $a_ipsec[$id]['interface'];
+       else
+               $pconfig['interface'] = "wan";
+               
+       list($pconfig['remotenet'],$pconfig['remotebits']) = explode("/", $a_ipsec[$id]['remote-subnet']);
+       $pconfig['remotegw'] = $a_ipsec[$id]['remote-gateway'];
+       $pconfig['p1mode'] = $a_ipsec[$id]['p1']['mode'];
+       
+       if (isset($a_ipsec[$id]['p1']['myident']['myaddress']))
+               $pconfig['p1myidentt'] = 'myaddress';
+       else if (isset($a_ipsec[$id]['p1']['myident']['address'])) {
+               $pconfig['p1myidentt'] = 'address';
+               $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['address'];
+       } else if (isset($a_ipsec[$id]['p1']['myident']['fqdn'])) {
+               $pconfig['p1myidentt'] = 'fqdn';
+               $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['fqdn'];
+       }
+       
+       $pconfig['p1ealgo'] = $a_ipsec[$id]['p1']['encryption-algorithm'];
+       $pconfig['p1halgo'] = $a_ipsec[$id]['p1']['hash-algorithm'];
+       $pconfig['p1dhgroup'] = $a_ipsec[$id]['p1']['dhgroup'];
+       $pconfig['p1lifetime'] = $a_ipsec[$id]['p1']['lifetime'];
+       $pconfig['p1pskey'] = $a_ipsec[$id]['p1']['pre-shared-key'];
+       $pconfig['p2proto'] = $a_ipsec[$id]['p2']['protocol'];
+       $pconfig['p2ealgos'] = $a_ipsec[$id]['p2']['encryption-algorithm-option'];
+       $pconfig['p2halgos'] = $a_ipsec[$id]['p2']['hash-algorithm-option'];
+       $pconfig['p2pfsgroup'] = $a_ipsec[$id]['p2']['pfsgroup'];
+       $pconfig['p2lifetime'] = $a_ipsec[$id]['p2']['lifetime'];
+       $pconfig['descr'] = $a_ipsec[$id]['descr'];
+       
+} else {
+       /* defaults */
+       $pconfig['interface'] = "wan";
+       $pconfig['localnet'] = "lan";
+       $pconfig['p1mode'] = "aggressive";
+       $pconfig['p1myidentt'] = "myaddress";
+       $pconfig['p1ealgo'] = "3des";
+       $pconfig['p1halgo'] = "md5";
+       $pconfig['p1dhgroup'] = "2";
+       $pconfig['p2proto'] = "esp";
+       $pconfig['p2ealgos'] = explode(",", "3des,blowfish,cast128,rijndael");
+       $pconfig['p2halgos'] = explode(",", "hmac_md5,hmac_sha1");
+       $pconfig['p2pfsgroup'] = "0";
+}
+
+if ($_POST) {
+       if (is_specialnet($_POST['localnettype'])) {
+               $_POST['localnet'] = $_POST['localnettype'];
+               $_POST['localnetmask'] = 0;
+       } else if ($_POST['localnettype'] == "single") {
+               $_POST['localnetmask'] = 32;
+       }
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "localnet remotenet remotebits remotegw p1pskey p2ealgos p2halgos");
+       $reqdfieldsn = explode(",", "Local network,Remote network,Remote network bits,Remote gateway,Pre-Shared Key,P2 Encryption Algorithms,P2 Hash Algorithms");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (!is_specialnet($_POST['localnettype'])) {
+               if (($_POST['localnet'] && !is_ipaddr($_POST['localnet']))) {
+                       $input_errors[] = "A valid local network IP address must be specified.";
+               }
+               if (($_POST['localnetmask'] && !is_numeric($_POST['localnetmask']))) {
+                       $input_errors[] = "A valid local network bit count must be specified.";
+               }
+       }
+       if (($_POST['p1lifetime'] && !is_numeric($_POST['p1lifetime']))) {
+               $input_errors[] = "The P1 lifetime must be an integer.";
+       }
+       if (($_POST['p2lifetime'] && !is_numeric($_POST['p2lifetime']))) {
+               $input_errors[] = "The P2 lifetime must be an integer.";
+       }
+       if ($_POST['remotebits'] && (!is_numeric($_POST['remotebits']) || ($_POST['remotebits'] <= 0) || ($_POST['remotebits'] > 32))) {
+               $input_errors[] = "The remote network bits are invalid.";
+       }
+       if (($_POST['remotenet'] && !is_ipaddr($_POST['remotenet']))) {
+               $input_errors[] = "A valid remote network address must be specified.";
+       }
+       if (($_POST['remotegw'] && !is_ipaddr($_POST['remotegw']))) {
+               $input_errors[] = "A valid remote gateway address must be specified.";
+       }
+       if ((($_POST['p1myidentt'] == "address") && !is_ipaddr($_POST['p1myident']))) {
+               $input_errors[] = "A valid IP address for 'My identifier' must be specified.";
+       }
+       if ((($_POST['p1myidentt'] == "fqdn") && !is_domain($_POST['p1myident']))) {
+               $input_errors[] = "A valid domain name for 'My identifier' must be specified.";
+       }
+       
+       if ($_POST['p1myidentt'] == "myaddress")
+               $_POST['p1myident'] = "";
+
+       if (!$input_errors) {
+               $ipsecent['disabled'] = $_POST['disabled'] ? true : false;
+               $ipsecent['interface'] = $pconfig['interface'];
+               pconfig_to_address($ipsecent['local-subnet'], $_POST['localnet'], $_POST['localnetmask']);
+               $ipsecent['remote-subnet'] = $_POST['remotenet'] . "/" . $_POST['remotebits'];
+               $ipsecent['remote-gateway'] = $_POST['remotegw'];
+               $ipsecent['p1']['mode'] = $_POST['p1mode'];
+               
+               $ipsecent['p1']['myident'] = array();
+               switch ($_POST['p1myidentt']) {
+                       case 'myaddress':
+                               $ipsecent['p1']['myident']['myaddress'] = true;
+                               break;
+                       case 'address':
+                               $ipsecent['p1']['myident']['address'] = $_POST['p1myident'];
+                               break;
+                       case 'fqdn':
+                               $ipsecent['p1']['myident']['fqdn'] = $_POST['p1myident'];
+                               break;
+               }
+               
+               $ipsecent['p1']['encryption-algorithm'] = $_POST['p1ealgo'];
+               $ipsecent['p1']['hash-algorithm'] = $_POST['p1halgo'];
+               $ipsecent['p1']['dhgroup'] = $_POST['p1dhgroup'];
+               $ipsecent['p1']['lifetime'] = $_POST['p1lifetime'];
+               $ipsecent['p1']['pre-shared-key'] = $_POST['p1pskey'];
+               $ipsecent['p2']['protocol'] = $_POST['p2proto'];
+               $ipsecent['p2']['encryption-algorithm-option'] = $_POST['p2ealgos'];
+               $ipsecent['p2']['hash-algorithm-option'] = $_POST['p2halgos'];
+               $ipsecent['p2']['pfsgroup'] = $_POST['p2pfsgroup'];
+               $ipsecent['p2']['lifetime'] = $_POST['p2lifetime'];
+               $ipsecent['descr'] = $_POST['descr'];
+               
+               if (isset($id) && $a_ipsec[$id])
+                       $a_ipsec[$id] = $ipsecent;
+               else
+                       $a_ipsec[] = $ipsecent;
+               
+               write_config();
+               touch($d_ipsecconfdirty_path);
+               
+               header("Location: vpn_ipsec.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: IPsec: Edit tunnel</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function typesel_change() {
+       switch (document.iform.localnettype.selectedIndex) {
+               case 0: /* single */
+                       document.iform.localnet.disabled = 0;
+                       document.iform.localnetmask.value = "";
+                       document.iform.localnetmask.disabled = 1;
+                       break;
+               case 1: /* network */
+                       document.iform.localnet.disabled = 0;
+                       document.iform.localnetmask.disabled = 0;
+                       break;
+               default:
+                       document.iform.localnet.value = "";
+                       document.iform.localnet.disabled = 1;
+                       document.iform.localnetmask.value = "";
+                       document.iform.localnetmask.disabled = 1;
+                       break;
+       }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec: Edit tunnel</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="vpn_ipsec_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Mode</td>
+                  <td width="78%" class="vtable"> Tunnel</td>
+                </tr>
+                               <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Disabled</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="disabled" type="checkbox" id="disabled" value="yes" <?php if ($pconfig['disabled']) echo "checked"; ?>>
+                    <strong>Disable this tunnel</strong><br>
+                    <span class="vexpl">Set this option to disable this tunnel without
+                                       removing it from the list.</span></td>
+                </tr>
+                               <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Interface</td>
+                  <td width="78%" class="vtable"> <select name="interface" class="formfld">
+                      <?php $interfaces = array('wan' => 'WAN', 'lan' => 'LAN');
+                                         for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+                                               $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+                                         }
+                                         foreach ($interfaces as $iface => $ifacename): ?>
+                      <option value="<?=$iface;?>" <?php if ($iface == $pconfig['interface']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($ifacename);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br>
+                    <span class="vexpl">Select the interface for the local endpoint of this tunnel.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Local subnet</td>
+                  <td width="78%" class="vtable"> 
+                    <table border="0" cellspacing="0" cellpadding="0">
+                      <tr> 
+                        <td>Type:&nbsp;&nbsp;</td>
+                        <td><select name="localnettype" class="formfld" onChange="typesel_change()">
+                            <?php $sel = is_specialnet($pconfig['localnet']); ?>
+                            <option value="single" <?php if (($pconfig['localnetmask'] == 32) && !$sel) { echo "selected"; $sel = 1; } ?>> 
+                            Single host</option>
+                            <option value="network" <?php if (!$sel) echo "selected"; ?>> 
+                            Network</option>
+                            <option value="lan" <?php if ($pconfig['localnet'] == "lan") { echo "selected"; } ?>> 
+                            LAN subnet</option>
+                          </select></td>
+                      </tr>
+                      <tr> 
+                        <td>Address:&nbsp;&nbsp;</td>
+                        <td><input name="localnet" type="text" class="formfld" id="localnet" size="20" value="<?php if (!is_specialnet($pconfig['localnet'])) echo htmlspecialchars($pconfig['localnet']);?>">
+                          / 
+                          <select name="localnetmask" class="formfld" id="localnetmask">
+                            <?php for ($i = 31; $i > 0; $i--): ?>
+                            <option value="<?=$i;?>" <?php if ($i == $pconfig['localnetmask']) echo "selected"; ?>>
+                            <?=$i;?>
+                            </option>
+                            <?php endfor; ?>
+                          </select> </td>
+                      </tr>
+                    </table></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Remote subnet</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="remotenet" type="text" class="formfld" id="remotenet" size="20" value="<?=$pconfig['remotenet'];?>">
+                    / 
+                    <select name="remotebits" class="formfld" id="remotebits">
+                      <?php for ($i = 32; $i > 0; $i--): ?>
+                      <option value="<?=$i;?>" <?php if ($i == $pconfig['remotebits']) echo "selected"; ?>> 
+                      <?=$i;?>
+                      </option>
+                      <?php endfor; ?>
+                    </select></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Remote gateway</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="remotegw" type="text" class="formfld" id="remotegw" size="20" value="<?=$pconfig['remotegw'];?>"> 
+                    <br>
+                    Enter the public IP address of the remote gateway</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Description</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="descr" type="text" class="formfld" id="descr" size="40" value="<?=htmlspecialchars($pconfig['descr']);?>"> 
+                    <br> <span class="vexpl">You may enter a description here 
+                    for your reference (not parsed).</span></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" class="list" height="12"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="listtopic">Phase 1 proposal 
+                    (Authentication)</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Negotiation mode</td>
+                  <td width="78%" class="vtable">
+<select name="p1mode" class="formfld">
+                      <?php $modes = explode(" ", "main aggressive"); foreach ($modes as $mode): ?>
+                      <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1mode']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($mode);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Aggressive is faster, but 
+                    less secure.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">My identifier</td>
+                  <td width="78%" class="vtable">
+<select name="p1myidentt" class="formfld">
+                      <?php foreach ($my_identifier_list as $mode => $modename): ?>
+                      <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1myidentt']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($modename);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <input name="p1myident" type="text" class="formfld" id="p1myident" size="30" value="<?=$pconfig['p1myident'];?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Encryption algorithm</td>
+                  <td width="78%" class="vtable">
+<select name="p1ealgo" class="formfld">
+                      <?php foreach ($p1_ealgos as $algo => $algoname): ?>
+                      <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1ealgo']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($algoname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Must match the setting 
+                    chosen on the remote side. </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Hash algorithm</td>
+                  <td width="78%" class="vtable">
+<select name="p1halgo" class="formfld">
+                      <?php foreach ($p1_halgos as $algo => $algoname): ?>
+                      <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1halgo']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($algoname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Must match the setting 
+                    chosen on the remote side. </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">DH key group</td>
+                  <td width="78%" class="vtable">
+<select name="p1dhgroup" class="formfld">
+                      <?php $keygroups = explode(" ", "1 2 5"); foreach ($keygroups as $keygroup): ?>
+                      <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p1dhgroup']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($keygroup);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024 
+                    bit, 5 = 1536 bit</em><br>
+                    Must match the setting chosen on the remote side. </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Lifetime</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="p1lifetime" type="text" class="formfld" id="p1lifetime" size="20" value="<?=$pconfig['p1lifetime'];?>">
+                    seconds</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Pre-Shared Key</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="p1pskey" type="text" class="formfld" id="p1pskey" size="40" value="<?=$pconfig['p1pskey'];?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td colspan="2" class="list" height="12"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="listtopic">Phase 2 proposal 
+                    (SA/Key Exchange)</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
+                  <td width="78%" class="vtable">
+<select name="p2proto" class="formfld">
+                      <?php foreach ($p2_protos as $proto => $protoname): ?>
+                      <option value="<?=$proto;?>" <?php if ($proto == $pconfig['p2proto']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($protoname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">ESP is encryption, AH is 
+                    authentication only </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Encryption algorithms</td>
+                  <td width="78%" class="vtable"> 
+                    <?php foreach ($p2_ealgos as $algo => $algoname): ?>
+                    <input type="checkbox" name="p2ealgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2ealgos'])) echo "checked"; ?>> 
+                    <?=htmlspecialchars($algoname);?>
+                    <br> 
+                    <?php endforeach; ?>
+                    <br>
+                    Hint: use 3DES for best compatibility or if you have a hardware 
+                    crypto accelerator card. Blowfish is usually the fastest in 
+                    software encryption. </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Hash algorithms</td>
+                  <td width="78%" class="vtable"> 
+                    <?php foreach ($p2_halgos as $algo => $algoname): ?>
+                    <input type="checkbox" name="p2halgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2halgos'])) echo "checked"; ?>> 
+                    <?=htmlspecialchars($algoname);?>
+                    <br> 
+                    <?php endforeach; ?>
+                    <br>
+                    Hint: MD5 is slightly faster than SHA1.</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">PFS key group</td>
+                  <td width="78%" class="vtable">
+<select name="p2pfsgroup" class="formfld">
+                      <?php foreach ($p2_pfskeygroups as $keygroup => $keygroupname): ?>
+                      <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p2pfsgroup']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($keygroupname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024 
+                    bit, 5 = 1536 bit</em></span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Lifetime</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="p2lifetime" type="text" class="formfld" id="p2lifetime" size="20" value="<?=$pconfig['p2lifetime'];?>">
+                    seconds</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_ipsec[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>"> 
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+typesel_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/vpn_ipsec_keys.php b/webgui/vpn_ipsec_keys.php
new file mode 100644 (file)
index 0000000..830d504
--- /dev/null
@@ -0,0 +1,106 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_ipsec_keys.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['mobilekey'])) {
+       $config['ipsec']['mobilekey'] = array();
+}
+ipsec_mobilekey_sort();
+$a_secret = &$config['ipsec']['mobilekey'];
+
+if ($_GET['act'] == "del") {
+       if ($a_secret[$_GET['id']]) {
+               unset($a_secret[$_GET['id']]);
+               write_config();
+               touch($d_ipsecconfdirty_path);
+               header("Location: vpn_ipsec_keys.php");
+               exit;
+       }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: IPsec</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec</p>
+<form action="vpn_ipsec.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (file_exists($d_ipsecconfdirty_path)): ?><p>
+<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="vpn_ipsec.php" class="tblnk">Tunnels</a></td>
+    <td nowrap class="tabinact"><a href="vpn_ipsec_mobile.php" class="tblnk">Mobile clients</a></td>
+    <td nowrap class="tabact">Pre-shared keys</td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="4" class="tabcont">
+              <table width="80%" border="0" cellpadding="0" cellspacing="0">
+                <tr> 
+                  <td class="listhdrr">Identifier</td>
+                  <td class="listhdr">Pre-shared key</td>
+                  <td class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_secret as $secretent): ?>
+                <tr> 
+                  <td class="listlr">
+                    <?=htmlspecialchars($secretent['ident']);?>
+                  </td>
+                  <td class="listr">
+                    <?=htmlspecialchars($secretent['pre-shared-key']);?>
+                  </td>
+                  <td class="list" nowrap> <a href="vpn_ipsec_keys_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="vpn_ipsec_keys.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this pre-shared key?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list" colspan="2"></td>
+                  <td class="list"> <a href="vpn_ipsec_keys_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+                        </td>
+                       </tr>
+               </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/vpn_ipsec_keys_edit.php b/webgui/vpn_ipsec_keys_edit.php
new file mode 100644 (file)
index 0000000..28baea2
--- /dev/null
@@ -0,0 +1,135 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_ipsec_keys_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['mobilekey'])) {
+       $config['ipsec']['mobilekey'] = array();
+}
+ipsec_mobilekey_sort();
+$a_secret = &$config['ipsec']['mobilekey'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_secret[$id]) {
+       $pconfig['ident'] = $a_secret[$id]['ident'];
+       $pconfig['psk'] = $a_secret[$id]['pre-shared-key'];
+}
+
+if ($_POST) {
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "ident psk");
+       $reqdfieldsn = explode(",", "Identifier,Pre-shared key");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (preg_match("/[^a-zA-Z0-9@\.\-]/", $_POST['ident']))
+               $input_errors[] = "The identifier contains invalid characters.";
+       
+       if (!$input_errors && !(isset($id) && $a_secret[$id])) {
+               /* make sure there are no dupes */
+               foreach ($a_secret as $secretent) {
+                       if ($secretent['ident'] == $_POST['ident']) {
+                               $input_errors[] = "Another entry with the same identifier already exists.";
+                               break;
+                       }
+               }
+       }
+
+       if (!$input_errors) {
+       
+               if (isset($id) && $a_secret[$id])
+                       $secretent = $a_secret[$id];
+       
+               $secretent['ident'] = $_POST['ident'];
+               $secretent['pre-shared-key'] = $_POST['psk'];
+               
+               if (isset($id) && $a_secret[$id])
+                       $a_secret[$id] = $secretent;
+               else
+                       $a_secret[] = $secretent;
+               
+               write_config();
+               touch($d_ipsecconfdirty_path);
+               
+               header("Location: vpn_ipsec_keys.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: IPsec: Edit pre-shared key</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec: Edit pre-shared key</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+            <form action="vpn_ipsec_keys_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td valign="top" class="vncellreq">Identifier</td>
+                  <td class="vtable">
+ <input name="ident" type="text" class="formfld" id="ident" size="30" value="<?=$pconfig['ident'];?>">
+                    <br>
+This can be either an IP address, fully qualified domain name or an e-mail address.       
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Pre-shared key</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="psk" type="text" class="formfld" id="psk" size="40" value="<?=$pconfig['psk'];?>">
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_secret[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/vpn_ipsec_mobile.php b/webgui/vpn_ipsec_mobile.php
new file mode 100644 (file)
index 0000000..d1bea14
--- /dev/null
@@ -0,0 +1,319 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_ipsec_mobile.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['ipsec']['mobileclients'])) {
+       $config['ipsec']['mobileclients'] = array();
+}
+$a_ipsec = &$config['ipsec']['mobileclients'];
+
+if (count($a_ipsec) == 0) {
+       /* defaults */
+       $pconfig['p1mode'] = "aggressive";
+       $pconfig['p1myidentt'] = "myaddress";
+       $pconfig['p1ealgo'] = "3des";
+       $pconfig['p1halgo'] = "md5";
+       $pconfig['p1dhgroup'] = "2";
+       $pconfig['p2proto'] = "esp";
+       $pconfig['p2ealgos'] = explode(",", "3des,blowfish,cast128,rijndael");
+       $pconfig['p2halgos'] = explode(",", "hmac_md5,hmac_sha1");
+       $pconfig['p2pfsgroup'] = "0";
+} else {
+       $pconfig['enable'] = isset($a_ipsec['enable']);
+       $pconfig['p1mode'] = $a_ipsec['p1']['mode'];
+               
+       if (isset($a_ipsec['p1']['myident']['myaddress']))
+               $pconfig['p1myidentt'] = 'myaddress';
+       else if (isset($a_ipsec['p1']['myident']['address'])) {
+               $pconfig['p1myidentt'] = 'address';
+               $pconfig['p1myident'] = $a_ipsec['p1']['myident']['address'];
+       } else if (isset($a_ipsec['p1']['myident']['fqdn'])) {
+               $pconfig['p1myidentt'] = 'fqdn';
+               $pconfig['p1myident'] = $a_ipsec['p1']['myident']['fqdn'];
+       }
+       
+       $pconfig['p1ealgo'] = $a_ipsec['p1']['encryption-algorithm'];
+       $pconfig['p1halgo'] = $a_ipsec['p1']['hash-algorithm'];
+       $pconfig['p1dhgroup'] = $a_ipsec['p1']['dhgroup'];
+       $pconfig['p1lifetime'] = $a_ipsec['p1']['lifetime'];
+       $pconfig['p2proto'] = $a_ipsec['p2']['protocol'];
+       $pconfig['p2ealgos'] = $a_ipsec['p2']['encryption-algorithm-option'];
+       $pconfig['p2halgos'] = $a_ipsec['p2']['hash-algorithm-option'];
+       $pconfig['p2pfsgroup'] = $a_ipsec['p2']['pfsgroup'];
+       $pconfig['p2lifetime'] = $a_ipsec['p2']['lifetime'];
+}
+
+if ($_POST) {
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       $reqdfields = explode(" ", "p2ealgos p2halgos");
+       $reqdfieldsn = explode(",", "P2 Encryption Algorithms,P2 Hash Algorithms");
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (($_POST['p1lifetime'] && !is_numeric($_POST['p1lifetime']))) {
+               $input_errors[] = "The P1 lifetime must be an integer.";
+       }
+       if (($_POST['p2lifetime'] && !is_numeric($_POST['p2lifetime']))) {
+               $input_errors[] = "The P2 lifetime must be an integer.";
+       }
+       if ((($_POST['p1myidentt'] == "address") && !is_ipaddr($_POST['p1myident']))) {
+               $input_errors[] = "A valid IP address for 'My identifier' must be specified.";
+       }
+       if ((($_POST['p1myidentt'] == "fqdn") && !is_domain($_POST['p1myident']))) {
+               $input_errors[] = "A valid domain name for 'My identifier' must be specified.";
+       }
+       
+       if ($_POST['p1myidentt'] == "myaddress")
+               $_POST['p1myident'] = "";
+
+       if (!$input_errors) {
+               $ipsecent = array();
+               $ipsecent['enable'] = $_POST['enable'] ? true : false;
+               $ipsecent['p1']['mode'] = $_POST['p1mode'];
+               
+               $ipsecent['p1']['myident'] = array();
+               switch ($_POST['p1myidentt']) {
+                       case 'myaddress':
+                               $ipsecent['p1']['myident']['myaddress'] = true;
+                               break;
+                       case 'address':
+                               $ipsecent['p1']['myident']['address'] = $_POST['p1myident'];
+                               break;
+                       case 'fqdn':
+                               $ipsecent['p1']['myident']['fqdn'] = $_POST['p1myident'];
+                               break;
+               }
+               
+               $ipsecent['p1']['encryption-algorithm'] = $_POST['p1ealgo'];
+               $ipsecent['p1']['hash-algorithm'] = $_POST['p1halgo'];
+               $ipsecent['p1']['dhgroup'] = $_POST['p1dhgroup'];
+               $ipsecent['p1']['lifetime'] = $_POST['p1lifetime'];
+               $ipsecent['p2']['protocol'] = $_POST['p2proto'];
+               $ipsecent['p2']['encryption-algorithm-option'] = $_POST['p2ealgos'];
+               $ipsecent['p2']['hash-algorithm-option'] = $_POST['p2halgos'];
+               $ipsecent['p2']['pfsgroup'] = $_POST['p2pfsgroup'];
+               $ipsecent['p2']['lifetime'] = $_POST['p2lifetime'];
+               
+               $a_ipsec = $ipsecent;
+               
+               write_config();
+               touch($d_ipsecconfdirty_path);
+               
+               header("Location: vpn_ipsec_mobile.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: IPsec</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: IPsec</p>
+<form action="vpn_ipsec.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_ipsecconfdirty_path)): ?><p>
+<?php print_info_box_np("The IPsec tunnel configuration has been changed.<br>You must apply the changes in order for them to take effect.");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+</form>
+<form action="vpn_ipsec_mobile.php" method="post" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+  <tr> 
+    <td nowrap class="tabinact"><a href="vpn_ipsec.php" class="tblnk">Tunnels</a></td>
+    <td nowrap class="tabact">Mobile clients</td>
+    <td nowrap class="tabinact"><a href="vpn_ipsec_keys.php" class="tblnk">Pre-shared keys</a></td>
+    <td width="100%">&nbsp;</td>
+  </tr>
+  <tr> 
+    <td colspan="4" class="tabcont">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                         <tr> 
+                        <td width="22%" valign="top">&nbsp;</td>
+                        <td width="78%"> 
+                    <input name="enable" type="checkbox" id="enable" value="yes" <?php if ($pconfig['enable']) echo "checked"; ?>>
+                    <strong>Allow mobile clients</strong></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="listtopic">Phase 1 proposal 
+                    (Authentication)</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Negotiation mode</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1mode" class="formfld">
+                      <?php $modes = explode(" ", "main aggressive"); foreach ($modes as $mode): ?>
+                      <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1mode']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($mode);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Aggressive is faster, but 
+                    less secure.</span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">My identifier</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1myidentt" class="formfld">
+                      <?php foreach ($my_identifier_list as $mode => $modename): ?>
+                      <option value="<?=$mode;?>" <?php if ($mode == $pconfig['p1myidentt']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($modename);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <input name="p1myident" type="text" class="formfld" id="p1myident" size="30" value="<?=$pconfig['p1myident'];?>"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Encryption algorithm</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1ealgo" class="formfld">
+                      <?php foreach ($p1_ealgos as $algo => $algoname): ?>
+                      <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1ealgo']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($algoname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Must match the setting 
+                    chosen on the remote side. </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Hash algorithm</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1halgo" class="formfld">
+                      <?php foreach ($p1_halgos as $algo => $algoname): ?>
+                      <option value="<?=$algo;?>" <?php if ($algo == $pconfig['p1halgo']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($algoname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">Must match the setting 
+                    chosen on the remote side. </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">DH key group</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p1dhgroup" class="formfld">
+                      <?php $keygroups = explode(" ", "1 2 5"); foreach ($keygroups as $keygroup): ?>
+                      <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p1dhgroup']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($keygroup);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024 
+                    bit, 5 = 1536 bit</em><br>
+                    Must match the setting chosen on the remote side. </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Lifetime</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable"> 
+                    <input name="p1lifetime" type="text" class="formfld" id="p1lifetime" size="20" value="<?=$pconfig['p1lifetime'];?>">
+                    seconds</td>
+                </tr>
+                <tr> 
+                  <td colspan="2" class="list" height="12"></td>
+                </tr>
+                <tr> 
+                  <td colspan="2" valign="top" class="listtopic">Phase 2 proposal 
+                    (SA/Key Exchange)</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Protocol</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p2proto" class="formfld">
+                      <?php foreach ($p2_protos as $proto => $protoname): ?>
+                      <option value="<?=$proto;?>" <?php if ($proto == $pconfig['p2proto']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($protoname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl">ESP is encryption, AH is 
+                    authentication only </span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Encryption algorithms</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable"> 
+                          <?php foreach ($p2_ealgos as $algo => $algoname): ?>
+                    <input type="checkbox" name="p2ealgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2ealgos'])) echo "checked"; ?>> 
+                    <?=htmlspecialchars($algoname);?>
+                    <br> 
+                    <?php endforeach; ?>
+                    <br>
+                    Hint: use 3DES for best compatibility or if you have a hardware 
+                    crypto accelerator card. Blowfish is usually the fastest in 
+                    software encryption. </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Hash algorithms</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable"> 
+                          <?php foreach ($p2_halgos as $algo => $algoname): ?>
+                    <input type="checkbox" name="p2halgos[]" value="<?=$algo;?>" <?php if (in_array($algo, $pconfig['p2halgos'])) echo "checked"; ?>> 
+                    <?=htmlspecialchars($algoname);?>
+                    <br> 
+                    <?php endforeach; ?>
+                    <br>
+                    Hint: MD5 is slightly faster than SHA1.</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">PFS key group</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable">
+<select name="p2pfsgroup" class="formfld">
+                      <?php foreach ($p2_pfskeygroups as $keygroup => $keygroupname): ?>
+                      <option value="<?=$keygroup;?>" <?php if ($keygroup == $pconfig['p2pfsgroup']) echo "selected"; ?>> 
+                      <?=htmlspecialchars($keygroupname);?>
+                      </option>
+                      <?php endforeach; ?>
+                    </select> <br> <span class="vexpl"><em>1 = 768 bit, 2 = 1024 
+                    bit, 5 = 1536 bit</em></span></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">Lifetime</td>
+                        <td width="78%" bgcolor="#FFFFFF" class="vtable"> 
+                    <input name="p2lifetime" type="text" class="formfld" id="p2lifetime" size="20" value="<?=$pconfig['p2lifetime'];?>">
+                    seconds</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save">
+                  </td>
+                </tr>
+              </table>
+                        </td>
+                       </tr>
+               </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/vpn_pptp.php b/webgui/vpn_pptp.php
new file mode 100644 (file)
index 0000000..90e7d8c
--- /dev/null
@@ -0,0 +1,289 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_pptp.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pptpd']['radius'])) {
+       $config['pptpd']['radius'] = array();
+}
+$pptpcfg = &$config['pptpd'];
+
+$pconfig['remoteip'] = $pptpcfg['remoteip'];
+$pconfig['localip'] = $pptpcfg['localip'];
+$pconfig['redir'] = $pptpcfg['redir'];
+$pconfig['mode'] = $pptpcfg['mode'];
+$pconfig['req128'] = isset($pptpcfg['req128']);
+$pconfig['radiusenable'] = isset($pptpcfg['radius']['enable']);
+$pconfig['radiusserver'] = $pptpcfg['radius']['server'];
+$pconfig['radiussecret'] = $pptpcfg['radius']['secret'];
+
+if ($_POST) {
+
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if ($_POST['mode'] == "server") {
+               $reqdfields = explode(" ", "localip remoteip");
+               $reqdfieldsn = explode(",", "Server address,Remote start address");
+               
+               if ($_POST['radiusenable']) {
+                       $reqdfields = array_merge($reqdfields, explode(" ", "radiusserver radiussecret"));
+                       $reqdfieldsn = array_merge($reqdfieldsn, 
+                               explode(",", "RADIUS server address,RADIUS shared secret"));
+               }
+               
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+               
+               if (($_POST['localip'] && !is_ipaddr($_POST['localip']))) {
+                       $input_errors[] = "A valid server address must be specified.";
+               }
+               if (($_POST['subnet'] && !is_ipaddr($_POST['remoteip']))) {
+                       $input_errors[] = "A valid remote start address must be specified.";
+               }
+               if (($_POST['radiusserver'] && !is_ipaddr($_POST['radiusserver']))) {
+                       $input_errors[] = "A valid RADIUS server address must be specified.";
+               }
+               
+               if (!$input_errors) {   
+                       $_POST['remoteip'] = $pconfig['remoteip'] = gen_subnet($_POST['remoteip'], $g['pptp_subnet']);
+                       $subnet_start = ip2long($_POST['remoteip']);
+                       $subnet_end = ip2long($_POST['remoteip']) + $g['n_pptp_units'] - 1;
+                                               
+                       if ((ip2long($_POST['localip']) >= $subnet_start) && 
+                           (ip2long($_POST['localip']) <= $subnet_end)) {
+                               $input_errors[] = "The specified server address lies in the remote subnet.";    
+                       }
+                       if ($_POST['localip'] == $config['interfaces']['lan']['ipaddr']) {
+                               $input_errors[] = "The specified server address is equal to the LAN interface address.";        
+                       }
+               }
+       } else if ($_POST['mode'] == "redir") {
+               $reqdfields = explode(" ", "redir");
+               $reqdfieldsn = explode(",", "PPTP redirection target address");
+               
+               do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+               
+               if (($_POST['redir'] && !is_ipaddr($_POST['redir']))) {
+                       $input_errors[] = "A valid target address must be specified.";
+               }
+       }
+
+       if (!$input_errors) {
+               $pptpcfg['remoteip'] = $_POST['remoteip'];
+               $pptpcfg['redir'] = $_POST['redir'];
+               $pptpcfg['localip'] = $_POST['localip'];
+               $pptpcfg['mode'] = $_POST['mode'];
+               $pptpcfg['req128'] = $_POST['req128'] ? true : false;
+               $pptpcfg['radius']['enable'] = $_POST['radiusenable'] ? true : false;
+               $pptpcfg['radius']['server'] = $_POST['radiusserver'];
+               $pptpcfg['radius']['secret'] = $_POST['radiussecret'];
+                       
+               write_config();
+               
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = vpn_pptpd_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: PPTP</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+<script language="JavaScript">
+<!--
+function get_radio_value(obj)
+{
+       for (i = 0; i < obj.length; i++) {
+               if (obj[i].checked)
+                       return obj[i].value;
+       }
+       return null;
+}
+
+function enable_change(enable_over) {
+       if ((get_radio_value(document.iform.mode) == "server") || enable_over) {
+               document.iform.remoteip.disabled = 0;
+               document.iform.localip.disabled = 0;
+               document.iform.req128.disabled = 0;
+               document.iform.radiusenable.disabled = 0;
+               
+               if (document.iform.radiusenable.checked || enable_over) {
+                       document.iform.radiusserver.disabled = 0;
+                       document.iform.radiussecret.disabled = 0;
+               } else {
+                       document.iform.radiusserver.disabled = 1;
+                       document.iform.radiussecret.disabled = 1;
+               }
+       } else {
+               document.iform.remoteip.disabled = 1;
+               document.iform.localip.disabled = 1;
+               document.iform.req128.disabled = 1;
+               document.iform.radiusenable.disabled = 1;
+               document.iform.radiusserver.disabled = 1;
+               document.iform.radiussecret.disabled = 1;
+       }
+       if ((get_radio_value(document.iform.mode) == "redir") || enable_over) {
+               document.iform.redir.disabled = 0;
+       } else {
+               document.iform.redir.disabled = 1;
+       }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: PPTP</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+            <form action="vpn_pptp.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="mode" type="radio" onclick="enable_change(false)" value="off"
+                                       <?php if (($pconfig['mode'] != "server") && ($pconfig['mode'] != "redir")) echo "checked";?>>
+                    Off</td>
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable">
+<input type="radio" name="mode" value="redir" onclick="enable_change(false)" <?php if ($pconfig['mode'] == "redir") echo "checked"; ?>>
+                    Redirect incoming PPTP connections to:</td>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">PPTP redirection</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="redir" type="text" class="formfld" id="redir" size="20" value="<?=htmlspecialchars($pconfig['redir']);?>"> 
+                    <br>
+                    Enter the IP address of a host which will accept incoming 
+                    PPTP connections.</td>
+                <tr> 
+                  <td width="22%" valign="top" class="vtable">&nbsp;</td>
+                  <td width="78%" class="vtable">
+<input type="radio" name="mode" value="server" onclick="enable_change(false)" <?php if ($pconfig['mode'] == "server") echo "checked"; ?>>
+                    Enable PPTP server</td>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Max. concurrent 
+                    connections</td>
+                  <td width="78%" class="vtable"> 
+                    <?=$g['n_pptp_units'];?>
+                  </td>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Server address</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="localip" type="text" class="formfld" id="localip" size="20" value="<?=htmlspecialchars($pconfig['localip']);?>"> 
+                    <br>
+                    Enter the IP address the PPTP server should use on its side 
+                    for all clients.</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Remote address 
+                    range</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="remoteip" type="text" class="formfld" id="remoteip" size="20" value="<?=htmlspecialchars($pconfig['remoteip']);?>">
+                    / 
+                    <?=$g['pptp_subnet'];?>
+                    <br>
+                    Specify the starting address for the client IP address subnet.<br>
+                    The PPTP server will assign 
+                    <?=$g['n_pptp_units'];?>
+                    addresses, starting at the address entered above, to clients.</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">RADIUS</td>
+                  <td width="78%" class="vtable"> 
+                    <p> 
+                      <input name="radiusenable" type="checkbox" id="radiusenable" onclick="enable_change(false)" value="yes" <?php if ($pconfig['radiusenable'] == "yes") echo "checked"; ?>>
+                      <strong>Use a RADIUS server for authentication<br>
+                      </strong>When set, all users will be authenticated using 
+                      the RADIUS server specified below. The local user database 
+                      will not be used.</p></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">RADIUS server </td>
+                  <td width="78%" class="vtable"> 
+                    <p> 
+                      <input name="radiusserver" type="text" class="formfld" id="radiusserver" size="20" value="<?=htmlspecialchars($pconfig['radiusserver']);?>">
+                      <br>
+                      Enter the IP address of the RADIUS server.</p></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top" class="vncell">RADIUS shared secret</td>
+                  <td width="78%" valign="top" class="vtable"> 
+                    <p> 
+                      <input name="radiussecret" type="password" class="formfld" id="radiussecret" size="20" value="<?=htmlspecialchars($pconfig['radiussecret']);?>">
+                      <br>
+                      Enter the shared secret that will be used to authenticate 
+                      to the RADIUS server.</p></td>
+                </tr>
+                <tr> 
+                  <td height="16" colspan="2" valign="top"></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="middle">&nbsp;</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="req128" type="checkbox" id="req128" value="yes" <?php if ($pconfig['req128'] == "yes") echo "checked"; ?>> 
+                    <strong>Require 128-bit encryption</strong><br>
+                    When set, 128-bit encryption will be accepted. Otherwise, 
+                    40-bit and 56-bit encryption will be accepted, too. Note that 
+                    encryption will always be forced on PPTP connections (i.e. 
+                    unencrypted connections will not be accepted).</td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save" onclick="enable_change(true)"> 
+                  </td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"><span class="vexpl"><span class="red"><strong>Note:<br>
+                    </strong></span>don't forget to add a firewall rule to permit 
+                    traffic from PPTP clients!</span></td>
+                </tr>
+              </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/vpn_pptp_users.php b/webgui/vpn_pptp_users.php
new file mode 100644 (file)
index 0000000..1f1b458
--- /dev/null
@@ -0,0 +1,110 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_pptp_users.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pptpd']['user'])) {
+       $config['pptpd']['user'] = array();
+}
+pptpd_users_sort();
+$a_secret = &$config['pptpd']['user'];
+
+if ($_POST) {
+
+       $pconfig = $_POST;
+
+       if ($_POST['apply']) {
+               $retval = 0;
+               if (!file_exists($d_sysrebootreqd_path)) {
+                       config_lock();
+                       $retval = vpn_pptpd_configure();
+                       config_unlock();
+               }
+               $savemsg = get_std_save_message($retval);
+               if ($retval == 0) {
+                       if (file_exists($d_pptpuserdirty_path))
+                               unlink($d_pptpuserdirty_path);
+               }
+       }
+}
+
+if ($_GET['act'] == "del") {
+       if ($a_secret[$_GET['id']]) {
+               unset($a_secret[$_GET['id']]);
+               write_config();
+               touch($d_pptpuserdirty_path);
+               header("Location: vpn_pptp_users.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: PPTP: Users</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: PPTP: Users</p>
+<form action="vpn_pptp_users.php" method="post">
+<?php if ($savemsg) print_info_box(htmlspecialchars($savemsg)); ?>
+<?php if (isset($config['pptpd']['radius']['enable']))
+       print_info_box(htmlspecialchars("Warning: RADIUS is enabled. The local user database will not be used.")); ?>
+<?php if (file_exists($d_pptpuserdirty_path)): ?><p>
+<?php print_info_box_np("The PPTP user list has been modified.<br>You must apply the changes in order for them to take effect.<br><b>Warning: this will terminate all current PPTP sessions!</b>");?><br>
+<input name="apply" type="submit" class="formbtn" id="apply" value="Apply changes"></p>
+<?php endif; ?>
+              <table width="50%" border="0" cellpadding="0" cellspacing="0">
+                <tr> 
+                  <td class="listhdrr">Username</td>
+                  <td class="list"></td>
+                               </tr>
+                         <?php $i = 0; foreach ($a_secret as $secretent): ?>
+                <tr> 
+                  <td class="listlr">
+                    <?=htmlspecialchars($secretent['name']);?>
+                  </td>
+                  <td class="list" nowrap> <a href="vpn_pptp_users_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+                     &nbsp;<a href="vpn_pptp_users.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this user?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+                         <?php $i++; endforeach; ?>
+                <tr> 
+                  <td class="list"></td>
+                  <td class="list"> <a href="vpn_pptp_users_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+                               </tr>
+              </table>
+            </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/vpn_pptp_users_edit.php b/webgui/vpn_pptp_users_edit.php
new file mode 100644 (file)
index 0000000..54661a2
--- /dev/null
@@ -0,0 +1,149 @@
+#!/usr/local/bin/php
+<?php
+/*
+       vpn_pptp_users_edit.php
+       part of m0n0wall (http://m0n0.ch/wall)
+       
+       Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+       All rights reserved.
+       
+       Redistribution and use in source and binary forms, with or without
+       modification, are permitted provided that the following conditions are met:
+       
+       1. Redistributions of source code must retain the above copyright notice,
+          this list of conditions and the following disclaimer.
+       
+       2. Redistributions in binary form must reproduce the above copyright
+          notice, this list of conditions and the following disclaimer in the
+          documentation and/or other materials provided with the distribution.
+       
+       THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
+       INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
+       AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
+       AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
+       OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+       INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+       CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+       ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+       POSSIBILITY OF SUCH DAMAGE.
+*/
+
+require("guiconfig.inc");
+
+if (!is_array($config['pptpd']['user'])) {
+       $config['pptpd']['user'] = array();
+}
+pptpd_users_sort();
+$a_secret = &$config['pptpd']['user'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+       $id = $_POST['id'];
+
+if (isset($id) && $a_secret[$id]) {
+       $pconfig['username'] = $a_secret[$id]['name'];
+}
+
+if ($_POST) {
+       
+       unset($input_errors);
+       $pconfig = $_POST;
+
+       /* input validation */
+       if (isset($id) && ($a_secret[$id])) {
+               $reqdfields = explode(" ", "username");
+               $reqdfieldsn = explode(",", "Username");
+       } else {
+               $reqdfields = explode(" ", "username password");
+               $reqdfieldsn = explode(",", "Username,Password");
+       }
+       
+       do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+       
+       if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['username']))
+               $input_errors[] = "The username contains invalid characters.";
+               
+       if (preg_match("/[^a-zA-Z0-9\.\-_]/", $_POST['password']))
+               $input_errors[] = "The password contains invalid characters.";
+       
+       if (($_POST['password']) && ($_POST['password'] != $_POST['password2'])) {
+               $input_errors[] = "The passwords do not match.";
+       }
+       
+       if (!$input_errors && !(isset($id) && $a_secret[$id])) {
+               /* make sure there are no dupes */
+               foreach ($a_secret as $secretent) {
+                       if ($secretent['name'] == $_POST['username']) {
+                               $input_errors[] = "Another entry with the same username already exists.";
+                               break;
+                       }
+               }
+       }
+
+       if (!$input_errors) {
+       
+               if (isset($id) && $a_secret[$id])
+                       $secretent = $a_secret[$id];
+       
+               $secretent['name'] = $_POST['username'];
+               
+               if ($_POST['password'])
+                       $secretent['password'] = $_POST['password'];
+               
+               if (isset($id) && $a_secret[$id])
+                       $a_secret[$id] = $secretent;
+               else
+                       $a_secret[] = $secretent;
+               
+               write_config();
+               touch($d_pptpuserdirty_path);
+               
+               header("Location: vpn_pptp_users.php");
+               exit;
+       }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title>m0n0wall webGUI - VPN: PPTP: Users: Edit</title>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<link href="gui.css" rel="stylesheet" type="text/css">
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">VPN: PPTP: Users: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) echo htmlspecialchars($savemsg); ?>
+            <form action="vpn_pptp_users_edit.php" method="post" name="iform" id="iform">
+              <table width="100%" border="0" cellpadding="6" cellspacing="0">
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Username</td>
+                  <td width="78%" class="vtable">
+<input name="username" type="text" class="formfld" id="username" size="20" value="<?=htmlspecialchars($pconfig['username']);?>"> 
+                  </td>
+                <tr> 
+                  <td width="22%" valign="top" class="vncellreq">Password</td>
+                  <td width="78%" class="vtable"> 
+                    <input name="password" type="password" class="formfld" id="password" size="20"> 
+                    <br> <input name="password2" type="password" class="formfld" id="password2" size="20"> 
+                    &nbsp;(confirmation)<?php if (isset($id) && $a_secret[$id]): ?><br>
+                    <span class="vexpl">If you want to change the users' password, 
+                    enter it here twice.</span><?php endif; ?></td>
+                </tr>
+                <tr> 
+                  <td width="22%" valign="top">&nbsp;</td>
+                  <td width="78%"> 
+                    <input name="Submit" type="submit" class="formbtn" value="Save"> 
+                    <?php if (isset($id) && $a_secret[$id]): ?>
+                    <input name="id" type="hidden" value="<?=$id;?>">
+                    <?php endif; ?>
+                  </td>
+                </tr>
+              </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/webgui/x.gif b/webgui/x.gif
new file mode 100644 (file)
index 0000000..c469c9a
Binary files /dev/null and b/webgui/x.gif differ