summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cf/conf/config.xml522
-rw-r--r--cf/conf/ez-ipupdate.cache0
-rw-r--r--conf.default/config.xml522
-rw-r--r--etc/auth.conf10
-rw-r--r--etc/disktab235
-rw-r--r--etc/fbtab4
-rw-r--r--etc/group15
-rw-r--r--etc/host.conf7
-rw-r--r--etc/hosts.allow5
-rw-r--r--etc/inc/captiveportal.inc642
-rw-r--r--etc/inc/config.inc551
-rw-r--r--etc/inc/filter.inc946
-rw-r--r--etc/inc/functions.inc41
-rw-r--r--etc/inc/globals.inc54
-rw-r--r--etc/inc/interfaces.inc740
-rw-r--r--etc/inc/openvpn.inc559
-rw-r--r--etc/inc/services.inc440
-rw-r--r--etc/inc/shaper.inc403
-rw-r--r--etc/inc/system.inc563
-rw-r--r--etc/inc/util.inc421
-rw-r--r--etc/inc/vpn.inc559
-rw-r--r--etc/inc/xmlparse.inc205
-rw-r--r--etc/login.conf316
-rw-r--r--etc/master.passwd26
-rw-r--r--etc/networks17
-rw-r--r--etc/pamd.conf55
-rw-r--r--etc/passwd10
-rw-r--r--etc/pccard.conf435
-rw-r--r--etc/platform1
-rw-r--r--etc/protocols146
-rw-r--r--etc/pubkey.pem6
-rwxr-xr-xetc/rc62
-rwxr-xr-xetc/rc.banner59
-rwxr-xr-xetc/rc.bootup147
-rwxr-xr-xetc/rc.dyndns.storecache8
-rwxr-xr-xetc/rc.firmware55
-rwxr-xr-xetc/rc.initial76
-rwxr-xr-xetc/rc.initial.defaults61
-rwxr-xr-xetc/rc.initial.password65
-rwxr-xr-xetc/rc.initial.ping47
-rwxr-xr-xetc/rc.initial.reboot55
-rwxr-xr-xetc/rc.initial.setlanip117
-rwxr-xr-xetc/rc.initial.setports303
-rwxr-xr-xetc/rc.newwanip83
-rwxr-xr-xetc/rc.prunecaptiveportal37
-rwxr-xr-xetc/rc.reboot5
-rwxr-xr-xetc/rc.shutdown17
-rw-r--r--etc/services2106
-rw-r--r--etc/shells12
-rwxr-xr-xetc/sshd62
-rw-r--r--etc/syslog.conf7
-rw-r--r--etc/ttys291
-rw-r--r--etc/version1
-rwxr-xr-xusr/local/bin/runmsntp.sh12
-rwxr-xr-xusr/local/captiveportal/index.php407
-rw-r--r--usr/local/captiveportal/radius_accounting.inc241
-rw-r--r--usr/local/captiveportal/radius_authentication.inc128
-rw-r--r--usr/local/etc/php.ini10
-rw-r--r--usr/local/lib/php.ini10
-rwxr-xr-xusr/local/sbin/ppp-linkup21
-rwxr-xr-xusr/local/sbin/vpn-linkdown7
-rwxr-xr-xusr/local/sbin/vpn-linkup7
-rwxr-xr-xusr/local/www/diag_backup.php126
-rwxr-xr-xusr/local/www/diag_defaults.php73
-rwxr-xr-xusr/local/www/diag_dhcp_leases.php189
-rwxr-xr-xusr/local/www/diag_ipsec_sad.php139
-rwxr-xr-xusr/local/www/diag_ipsec_spd.php155
-rwxr-xr-xusr/local/www/diag_logs.php102
-rwxr-xr-xusr/local/www/diag_logs_dhcp.php103
-rwxr-xr-xusr/local/www/diag_logs_filter.php190
-rwxr-xr-xusr/local/www/diag_logs_settings.php202
-rwxr-xr-xusr/local/www/diag_logs_vpn.php111
-rwxr-xr-xusr/local/www/diag_ping.php113
-rwxr-xr-xusr/local/www/diag_resetstate.php97
-rwxr-xr-xusr/local/www/edit.php128
-rwxr-xr-xusr/local/www/exec.php240
-rwxr-xr-xusr/local/www/exec_raw.php38
-rwxr-xr-xusr/local/www/fbegin.inc131
-rwxr-xr-xusr/local/www/fend.inc8
-rwxr-xr-xusr/local/www/firewall_aliases.php127
-rwxr-xr-xusr/local/www/firewall_aliases_edit.php195
-rwxr-xr-xusr/local/www/firewall_nat.php171
-rwxr-xr-xusr/local/www/firewall_nat_1to1.php145
-rwxr-xr-xusr/local/www/firewall_nat_1to1_edit.php216
-rwxr-xr-xusr/local/www/firewall_nat_edit.php365
-rwxr-xr-xusr/local/www/firewall_nat_out.php184
-rwxr-xr-xusr/local/www/firewall_nat_out_edit.php311
-rwxr-xr-xusr/local/www/firewall_nat_server.php143
-rwxr-xr-xusr/local/www/firewall_nat_server_edit.php153
-rwxr-xr-xusr/local/www/firewall_rules.php268
-rwxr-xr-xusr/local/www/firewall_rules_edit.php773
-rwxr-xr-xusr/local/www/firewall_shaper.php269
-rwxr-xr-xusr/local/www/firewall_shaper_edit.php776
-rwxr-xr-xusr/local/www/firewall_shaper_queues.php141
-rwxr-xr-xusr/local/www/firewall_shaper_queues_edit.php187
-rwxr-xr-xusr/local/www/graph.php325
-rwxr-xr-xusr/local/www/gui.css271
-rwxr-xr-xusr/local/www/guiconfig.inc442
-rwxr-xr-xusr/local/www/ifstats.cgibin0 -> 4136 bytes
-rwxr-xr-xusr/local/www/index.php180
-rwxr-xr-xusr/local/www/interfaces.php630
-rwxr-xr-xusr/local/www/interfaces_assign.php265
-rwxr-xr-xusr/local/www/interfaces_lan.php173
-rwxr-xr-xusr/local/www/interfaces_opt.php276
-rwxr-xr-xusr/local/www/interfaces_vlan.php149
-rwxr-xr-xusr/local/www/interfaces_vlan_edit.php146
-rwxr-xr-xusr/local/www/interfaces_wan.php630
-rwxr-xr-xusr/local/www/interfaces_wlan.inc182
-rwxr-xr-xusr/local/www/license.php187
-rwxr-xr-xusr/local/www/logobig.jpgbin0 -> 7911 bytes
-rwxr-xr-xusr/local/www/reboot.php66
-rwxr-xr-xusr/local/www/services_captiveportal.php396
-rwxr-xr-xusr/local/www/services_captiveportal_ip.php152
-rwxr-xr-xusr/local/www/services_captiveportal_ip_edit.php152
-rwxr-xr-xusr/local/www/services_captiveportal_mac.php133
-rwxr-xr-xusr/local/www/services_captiveportal_mac_edit.php134
-rwxr-xr-xusr/local/www/services_dhcp.php337
-rwxr-xr-xusr/local/www/services_dhcp_edit.php176
-rwxr-xr-xusr/local/www/services_dhcp_relay.php229
-rwxr-xr-xusr/local/www/services_dnsmasq.php168
-rwxr-xr-xusr/local/www/services_dnsmasq_edit.php160
-rwxr-xr-xusr/local/www/services_dyndns.php197
-rwxr-xr-xusr/local/www/services_proxyarp.php124
-rwxr-xr-xusr/local/www/services_proxyarp_edit.php231
-rwxr-xr-xusr/local/www/services_snmp.php145
-rwxr-xr-xusr/local/www/services_wol.php162
-rwxr-xr-xusr/local/www/services_wol_edit.php143
-rwxr-xr-xusr/local/www/status.php150
-rwxr-xr-xusr/local/www/status_captiveportal.php128
-rwxr-xr-xusr/local/www/status_graph.php80
-rwxr-xr-xusr/local/www/status_interfaces.php283
-rwxr-xr-xusr/local/www/status_wireless.php189
-rwxr-xr-xusr/local/www/system.php260
-rwxr-xr-xusr/local/www/system_advanced.php289
-rwxr-xr-xusr/local/www/system_firmware.php206
-rwxr-xr-xusr/local/www/system_routes.php126
-rwxr-xr-xusr/local/www/system_routes_edit.php176
-rwxr-xr-xusr/local/www/vpn_ipsec.php192
-rwxr-xr-xusr/local/www/vpn_ipsec_edit.php527
-rwxr-xr-xusr/local/www/vpn_ipsec_keys.php107
-rwxr-xr-xusr/local/www/vpn_ipsec_keys_edit.php135
-rwxr-xr-xusr/local/www/vpn_ipsec_mobile.php330
-rwxr-xr-xusr/local/www/vpn_openvpn.php366
-rwxr-xr-xusr/local/www/vpn_openvpn_cli.php148
-rwxr-xr-xusr/local/www/vpn_openvpn_cli_edit.php353
-rwxr-xr-xusr/local/www/vpn_pptp.php309
-rwxr-xr-xusr/local/www/vpn_pptp_users.php126
-rwxr-xr-xusr/local/www/vpn_pptp_users_edit.php159
-rwxr-xr-xusr/sbin/config_lock.sh9
-rwxr-xr-xusr/sbin/config_unlock.sh9
150 files changed, 31162 insertions, 0 deletions
diff --git a/cf/conf/config.xml b/cf/conf/config.xml
new file mode 100644
index 0000000..1dba5ab
--- /dev/null
+++ b/cf/conf/config.xml
@@ -0,0 +1,522 @@
+<?xml version="1.0"?>
+<!-- m0n0wall default system configuration -->
+<m0n0wall>
+ <version>1.4</version>
+ <lastchange></lastchange>
+ <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/>
+ <expanddiags/>
+ <noantilockout></noantilockout>
+ -->
+ </webgui>
+ <!-- <disableconsolemenu/> -->
+ <!-- <disablefirmwarecheck/> -->
+ <!-- <shellcmd></shellcmd> -->
+ <!-- <earlyshellcmd></earlyshellcmd> -->
+ <!-- <harddiskstandby></harddiskstandby> -->
+ </system>
+ <interfaces>
+ <lan>
+ <if>sis0</if>
+ <ipaddr>192.168.1.1</ipaddr>
+ <subnet>24</subnet>
+ <media></media>
+ <mediaopt></mediaopt>
+ <!--
+ <wireless>
+ *see below (opt[n])*
+ </wireless>
+ -->
+ </lan>
+ <wan>
+ <if>sis1</if>
+ <mtu></mtu>
+ <ipaddr>dhcp</ipaddr>
+ <!-- *or* ipv4-address *or* 'pppoe' *or* 'pptp' *or* 'bigpond' -->
+ <subnet></subnet>
+ <gateway></gateway>
+ <blockpriv/>
+ <dhcphostname></dhcphostname>
+ <media></media>
+ <mediaopt></mediaopt>
+ <!--
+ <wireless>
+ *see below (opt[n])*
+ </wireless>
+ -->
+ </wan>
+ <!--
+ <opt[n]>
+ <enable/>
+ <descr></descr>
+ <if></if>
+ <ipaddr></ipaddr>
+ <subnet></subnet>
+ <media></media>
+ <mediaopt></mediaopt>
+ <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>
+ <!--
+ <vlans>
+ <vlan>
+ <tag></tag>
+ <if></if>
+ <descr></descr>
+ </vlan>
+ </vlans>
+ -->
+ <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>
+ <!--
+ <ondemand/>
+ <timeout></timeout>
+ -->
+ </pppoe>
+ <pptp>
+ <username></username>
+ <password></password>
+ <local></local>
+ <subnet></subnet>
+ <remote></remote>
+ <!--
+ <ondemand/>
+ <timeout></timeout>
+ -->
+ </pptp>
+ <bigpond>
+ <username></username>
+ <password></password>
+ <authserver></authserver>
+ <authdomain></authdomain>
+ <minheartbeatinterval></minheartbeatinterval>
+ </bigpond>
+ <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>
+ <gateway>xxx.xxx.xxx.xxx</gateway>
+ <domain></domain>
+ <dnsserver></dnsserver>
+ <next-server></next-server>
+ <filename></filename>
+ -->
+ </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>
+ <!-- <accounting/> -->
+ <!--
+ <user>
+ <name></name>
+ <password></password>
+ </user>
+ -->
+ </pptpd>
+ <ovpn>
+ <!--
+ <server>
+ <enable/>
+ <ca_cert></ca_cert>
+ <srv_cert></srv_cert>
+ <srv_key></srv_key>
+ <dh_param></dh_param>
+ <verb></verb>
+ <tun_iface></tun_iface>
+ <port></port>
+ <bind_iface></bind_iface>
+ <cli2cli/>
+ <maxcli></maxcli>
+ <prefix></prefix>
+ <ipblock></ipblock>
+ <crypto></crypto>
+ <dupcn/>
+ <psh_options>
+ <redir></redir>
+ <redir_loc></redir_loc>
+ <rte_delay></rte_delay>
+ <ping></ping>
+ <pingrst></pingrst>
+ <pingexit></pingexit>
+ <inact></inact>
+ </psh_options>
+ </server>
+ <client>
+ <tunnel></tunnel>
+ <ca_cert></ca_cert>
+ <cli_cert></cli_cert>
+ <cli_key></cli_key>
+ <type></type>
+ <tunnel>
+ <if></if>
+ <proto></proto>
+ <cport></cport>
+ <saddr></saddr>
+ <sport></sport>
+ <crypto></crypto>
+ </tunnel>
+ </client>
+ -->
+ </ovpn>
+ <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>
+ <!--
+ <captiveportal>
+ <enable/>
+ <interface>lan|opt[n]</interface>
+ <idletimeout>minutes</idletimeout>
+ <timeout>minutes</timeout>
+ <page>
+ <htmltext></htmltext>
+ <errtext></errtext>
+ </page>
+ <httpslogin/>
+ <httpsname></httpsname>
+ <certificate></certificate>
+ <private-key></private-key>
+ <redirurl></redirurl>
+ <radiusip></radiusip>
+ <radiusport></radiusport>
+ <radiuskey></radiuskey>
+ <nomacfilter/>
+ </captiveportal>
+ -->
+ <nat>
+ <!--
+ <rule>
+ <interface></interface>
+ <external-address></external-address>
+ <protocol></protocol>
+ <external-port></external-port>
+ <target></target>
+ <local-port></local-port>
+ <descr></descr>
+ </rule>
+ -->
+ <!--
+ <onetoone>
+ <interface></interface>
+ <external>xxx.xxx.xxx.xxx</external>
+ <internal>xxx.xxx.xxx.xxx</internal>
+ <subnet></subnet>
+ <descr></descr>
+ </onetoone>
+ -->
+ <!--
+ <advancedoutbound>
+ <enable/>
+ <rule>
+ <interface></interface>
+ <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>
+ <!-- <tcpidletimeout></tcpidletimeout> -->
+ <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>
+ <icmptype></icmptype>
+ <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>
+ <disabled/>
+ <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>
+ <iptos>(!)lowdelay,throughput,reliability,mincost,congestion</iptos>
+ <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/>
+ <auto/>
+ <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>
+ <wol>
+ <!--
+ <wolentry>
+ <interface>lan|opt[n]</interface>
+ <mac>xx:xx:xx:xx:xx:xx</mac>
+ <descr></descr>
+ </wolentry>
+ -->
+ </wol>
+</m0n0wall>
diff --git a/cf/conf/ez-ipupdate.cache b/cf/conf/ez-ipupdate.cache
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/cf/conf/ez-ipupdate.cache
diff --git a/conf.default/config.xml b/conf.default/config.xml
new file mode 100644
index 0000000..1dba5ab
--- /dev/null
+++ b/conf.default/config.xml
@@ -0,0 +1,522 @@
+<?xml version="1.0"?>
+<!-- m0n0wall default system configuration -->
+<m0n0wall>
+ <version>1.4</version>
+ <lastchange></lastchange>
+ <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/>
+ <expanddiags/>
+ <noantilockout></noantilockout>
+ -->
+ </webgui>
+ <!-- <disableconsolemenu/> -->
+ <!-- <disablefirmwarecheck/> -->
+ <!-- <shellcmd></shellcmd> -->
+ <!-- <earlyshellcmd></earlyshellcmd> -->
+ <!-- <harddiskstandby></harddiskstandby> -->
+ </system>
+ <interfaces>
+ <lan>
+ <if>sis0</if>
+ <ipaddr>192.168.1.1</ipaddr>
+ <subnet>24</subnet>
+ <media></media>
+ <mediaopt></mediaopt>
+ <!--
+ <wireless>
+ *see below (opt[n])*
+ </wireless>
+ -->
+ </lan>
+ <wan>
+ <if>sis1</if>
+ <mtu></mtu>
+ <ipaddr>dhcp</ipaddr>
+ <!-- *or* ipv4-address *or* 'pppoe' *or* 'pptp' *or* 'bigpond' -->
+ <subnet></subnet>
+ <gateway></gateway>
+ <blockpriv/>
+ <dhcphostname></dhcphostname>
+ <media></media>
+ <mediaopt></mediaopt>
+ <!--
+ <wireless>
+ *see below (opt[n])*
+ </wireless>
+ -->
+ </wan>
+ <!--
+ <opt[n]>
+ <enable/>
+ <descr></descr>
+ <if></if>
+ <ipaddr></ipaddr>
+ <subnet></subnet>
+ <media></media>
+ <mediaopt></mediaopt>
+ <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>
+ <!--
+ <vlans>
+ <vlan>
+ <tag></tag>
+ <if></if>
+ <descr></descr>
+ </vlan>
+ </vlans>
+ -->
+ <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>
+ <!--
+ <ondemand/>
+ <timeout></timeout>
+ -->
+ </pppoe>
+ <pptp>
+ <username></username>
+ <password></password>
+ <local></local>
+ <subnet></subnet>
+ <remote></remote>
+ <!--
+ <ondemand/>
+ <timeout></timeout>
+ -->
+ </pptp>
+ <bigpond>
+ <username></username>
+ <password></password>
+ <authserver></authserver>
+ <authdomain></authdomain>
+ <minheartbeatinterval></minheartbeatinterval>
+ </bigpond>
+ <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>
+ <gateway>xxx.xxx.xxx.xxx</gateway>
+ <domain></domain>
+ <dnsserver></dnsserver>
+ <next-server></next-server>
+ <filename></filename>
+ -->
+ </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>
+ <!-- <accounting/> -->
+ <!--
+ <user>
+ <name></name>
+ <password></password>
+ </user>
+ -->
+ </pptpd>
+ <ovpn>
+ <!--
+ <server>
+ <enable/>
+ <ca_cert></ca_cert>
+ <srv_cert></srv_cert>
+ <srv_key></srv_key>
+ <dh_param></dh_param>
+ <verb></verb>
+ <tun_iface></tun_iface>
+ <port></port>
+ <bind_iface></bind_iface>
+ <cli2cli/>
+ <maxcli></maxcli>
+ <prefix></prefix>
+ <ipblock></ipblock>
+ <crypto></crypto>
+ <dupcn/>
+ <psh_options>
+ <redir></redir>
+ <redir_loc></redir_loc>
+ <rte_delay></rte_delay>
+ <ping></ping>
+ <pingrst></pingrst>
+ <pingexit></pingexit>
+ <inact></inact>
+ </psh_options>
+ </server>
+ <client>
+ <tunnel></tunnel>
+ <ca_cert></ca_cert>
+ <cli_cert></cli_cert>
+ <cli_key></cli_key>
+ <type></type>
+ <tunnel>
+ <if></if>
+ <proto></proto>
+ <cport></cport>
+ <saddr></saddr>
+ <sport></sport>
+ <crypto></crypto>
+ </tunnel>
+ </client>
+ -->
+ </ovpn>
+ <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>
+ <!--
+ <captiveportal>
+ <enable/>
+ <interface>lan|opt[n]</interface>
+ <idletimeout>minutes</idletimeout>
+ <timeout>minutes</timeout>
+ <page>
+ <htmltext></htmltext>
+ <errtext></errtext>
+ </page>
+ <httpslogin/>
+ <httpsname></httpsname>
+ <certificate></certificate>
+ <private-key></private-key>
+ <redirurl></redirurl>
+ <radiusip></radiusip>
+ <radiusport></radiusport>
+ <radiuskey></radiuskey>
+ <nomacfilter/>
+ </captiveportal>
+ -->
+ <nat>
+ <!--
+ <rule>
+ <interface></interface>
+ <external-address></external-address>
+ <protocol></protocol>
+ <external-port></external-port>
+ <target></target>
+ <local-port></local-port>
+ <descr></descr>
+ </rule>
+ -->
+ <!--
+ <onetoone>
+ <interface></interface>
+ <external>xxx.xxx.xxx.xxx</external>
+ <internal>xxx.xxx.xxx.xxx</internal>
+ <subnet></subnet>
+ <descr></descr>
+ </onetoone>
+ -->
+ <!--
+ <advancedoutbound>
+ <enable/>
+ <rule>
+ <interface></interface>
+ <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>
+ <!-- <tcpidletimeout></tcpidletimeout> -->
+ <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>
+ <icmptype></icmptype>
+ <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>
+ <disabled/>
+ <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>
+ <iptos>(!)lowdelay,throughput,reliability,mincost,congestion</iptos>
+ <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/>
+ <auto/>
+ <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>
+ <wol>
+ <!--
+ <wolentry>
+ <interface>lan|opt[n]</interface>
+ <mac>xx:xx:xx:xx:xx:xx</mac>
+ <descr></descr>
+ </wolentry>
+ -->
+ </wol>
+</m0n0wall>
diff --git a/etc/auth.conf b/etc/auth.conf
new file mode 100644
index 0000000..3062d37
--- /dev/null
+++ b/etc/auth.conf
@@ -0,0 +1,10 @@
+#
+# $FreeBSD: src/etc/auth.conf,v 1.4.2.1 2001/07/13 14:37:26 dd Exp $
+#
+# This file contains information on what types of authentication to use.
+# It is just the beginnings of a greater scheme.
+
+# crypt_default = md5 des
+# auth_list = passwd kerberos
+
+auth_list = passwd
diff --git a/etc/disktab b/etc/disktab
new file mode 100644
index 0000000..43ebdf9
--- /dev/null
+++ b/etc/disktab
@@ -0,0 +1,235 @@
+# $FreeBSD: src/etc/etc.i386/disktab,v 1.20.2.2 2002/04/15 00:44:15 dougb Exp $
+#
+# Disk geometry and partition layout tables.
+# Key:
+# dt controller type
+# ty type of disk (fixed, removeable, simulated)
+# d[0-4] drive-type-dependent parameters
+# ns #sectors/track
+# nt #tracks/cylinder
+# nc #cylinders/disk
+# sc #sectors/cylinder, ns*nt default
+# su #sectors/unit, sc*nc default
+# se sector size, DEV_BSIZE default
+# rm rpm, 3600 default
+# sf supports bad144-style bad sector forwarding
+# sk sector skew per track, default 0
+# cs sector skew per cylinder, default 0
+# hs headswitch time, default 0
+# ts one-cylinder seek time, default 0
+# il sector interleave (n:1), 1 default
+# bs boot block size, default BBSIZE
+# sb superblock size, default SBSIZE
+# o[a-h] partition offsets in sectors
+# p[a-h] partition sizes in sectors
+# b[a-h] partition block sizes in bytes
+# f[a-h] partition fragment sizes in bytes
+# t[a-h] partition types (filesystem, swap, etc)
+#
+# All partition sizes reserve space for bad sector tables.
+# (5 cylinders needed for maintenance + replacement sectors)
+#
+
+#
+# Floppy formats:
+#
+# To make a filesystem on a floppy:
+# fdformat [-f <size>] fd<drive>[.<size>]
+# disklabel -B -r -w fd<drive>[.<size>] fd<size>
+# newfs <opts> fd<drive>[.<size>]
+#
+# with <opts>:
+# -t 2 - two heads
+# -u 9|15|18 - sectors per track
+# (using the default value of 1/4096 is not much useful for floppies)
+# -l 1 - interleave 1 (for most floppies)
+# -i 65536 - bytes of data per i-node
+# (the default -i value will render you with a floppy wasting way
+# too much space in i-node areas)
+#
+
+fd360:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#40:\
+ :pa#720:oa#0:ba#4096:fa#512:\
+ :pb#720:ob#0:bb#4096:fb#512:\
+ :pc#720:oc#0:bc#4096:fc#512:
+
+fd720:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#9:nc#80:\
+ :pa#1440:oa#0:ba#4096:fa#512:\
+ :pb#1440:ob#0:bb#4096:fb#512:\
+ :pc#1440:oc#0:bc#4096:fc#512:
+
+fd1200|floppy5|5in|5.25in High Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#360:ns#15:nc#80:\
+ :pa#2400:oa#0:ba#4096:fa#512:\
+ :pb#2400:ob#0:bb#4096:fb#512:\
+ :pc#2400:oc#0:bc#4096:fc#512:
+
+fd1440|floppy|floppy3|3in|3.5in High Density Floppy:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#18:nc#80:\
+ :pa#2880:oa#0:ba#4096:fa#512:\
+ :pb#2880:ob#0:bb#4096:fb#512:\
+ :pc#2880:oc#0:bc#4096:fc#512:
+
+#
+# Stressed floppy-formats. No guarantees given.
+#
+
+fd800:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#10:nc#80:\
+ :pa#1600:oa#0:ba#4096:fa#512:\
+ :pb#1600:ob#0:bb#4096:fb#512:\
+ :pc#1600:oc#0:bc#4096:fc#512:
+
+fd820:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#10:nc#82:\
+ :pa#1640:oa#0:ba#4096:fa#512:\
+ :pb#1640:ob#0:bb#4096:fb#512:\
+ :pc#1640:oc#0:bc#4096:fc#512:
+
+fd1480:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#18:nc#82:\
+ :pa#2952:oa#0:ba#4096:fa#512:\
+ :pb#2952:ob#0:bb#4096:fb#512:\
+ :pc#2952:oc#0:bc#4096:fc#512:
+
+fd1720:\
+ :ty=floppy:se#512:nt#2:rm#300:ns#21:nc#82:\
+ :pa#3444:oa#0:ba#4096:fa#512:\
+ :pb#3444:ob#0:bb#4096:fb#512:\
+ :pc#3444:oc#0:bc#4096:fc#512:
+
+#
+# LS-120 floppy-format.
+#
+fd120m|floppy120|floppy120m|3.5in LS-120 Floppy:\
+ :ty=floppy:se#512:nt#8:rm#300:ns#32:nc#963:\
+ :pa#246528:oa#0:ba#4096:fa#512:\
+ :pb#246528:ob#0:bb#4096:fb#512:\
+ :pc#246528:oc#0:bc#4096:fc#512:
+
+#
+# Harddisk formats
+#
+qp120at|Quantum Peripherals 120MB IDE:\
+ :dt=ESDI:ty=winchester:se#512:nt#9:ns#32:nc#813:sf: \
+ :pa#13824:oa#0:ta=4.2BSD:ba#4096:fa#512: \
+ :pb#13824:ob#13824:tb=swap: \
+ :pc#234144:oc#0: \
+ :ph#206496:oh#27648:th=4.2BSD:bh#4096:fh#512:
+
+pan60|Panasonic Laptop's 60MB IDE:\
+ :dt=ST506:ty=winchester:se#512:nt#13:ns#17:nc#565:\
+ :pa#13260:oa#0:ta=4.2BSD:ba#4096:fa#512:\
+ :pb#13260:ob#13260:tb=swap: \
+ :pc#124865:oc#0: \
+ :ph#97682:oh#26520:th=4.2BSD:bh#4096:fh#512:
+
+mk156|toshiba156|Toshiba MK156 156Mb:\
+ :dt=SCSI:ty=winchester:se#512:nt#10:ns#35:nc#825:\
+ :pa#15748:oa#0:ba#4096:fa#512:ta=4.2BSD:\
+ :pb#15748:ob#15748:tb=swap:\
+ :pc#288750:oc#0:\
+ :ph#257250:oh#31500:bh#4096:fh#512:th=4.2BSD:
+
+cp3100|Connor Peripherals 100MB IDE:\
+ :dt=ST506:ty=winchester:se#512:nt#8:ns#33:nc#766: \
+ :pa#12144:oa#0:ta=4.2BSD:ba#4096:fa#512: \
+ :pb#12144:ob#12144:tb=swap: \
+ :pc#202224:oc#0: \
+ :ph#177936:oh#24288:th=4.2BSD:bh#4096:fh#512:
+
+# a == root
+# b == swap
+# c == d == whole disk
+# e == /var
+# f == scratch
+# h == /usr
+
+cp3100new|Connor Peripherals 100MB IDE, with a different configuration:\
+ :dt=ST506:ty=winchester:se#512:nt#8:ns#33:nc#766: \
+ :pa#15840:oa#0:ta=4.2BSD:ba#4096:fa#512: \
+ :pb#24288:ob#15840:tb=swap: \
+ :pc#202224:oc#0: \
+ :pd#202224:od#0: \
+ :pe#15840:oe#40128:te=4.2BSD:be#4096:fe#512: \
+ :pg#15840:og#55968:tg=4.2BSD:bg#4096:fg#512: \
+ :ph#130416:oh#71808:th=4.2BSD:bh#4096:fh#512:
+
+maxtor4380|Maxtor XT4380E ESDI :\
+ :dt=ESDI:ty=winchester:se#512:nt#15:ns#36:nc#1222:sf: \
+ :pa#21600:oa#0:ta=4.2BSD:ba#4096:fa#512:\
+ :pb#21600:ob#21600:tb=swap: \
+ :pc#659880:oc#0: \
+ :pd#216000:od#53200:td=4.2BSD:bd#4096:fd#512: \
+ :ph#398520:oh#269200:th=4.2BSD:bh#4096:fh#512:
+
+miniscribe9380|compaq38|Miniscribe 9380 ESDI :\
+ :ty=winchester:dt=ESDI:se#512:nt#15:ns#35:nc#1223:rm#3600:sf: \
+ :pa#21000:oa#0:ba#8192:fa#1024:ta=4.2BSD: \
+ :pb#42000:ob#21000:tb=swap: \
+ :pc#642075:oc#0: \
+ :pd#21000:od#63000:bd#8192:fd#1024:td=4.2BSD: \
+ :ph#556500:oh#84000:bh#8192:fh#1024:th=4.2BSD:
+
+ida4|compaq88|Compaq IDA (4 drives) :\
+ :ty=winchester:dt=IDA:se#512:nt#16:ns#63:nc#1644:rm#3600:\
+ :pa#20160:oa#0:ba#8192:fa#1024:ta=4.2BSD: \
+ :pb#80640:ob#20160:tb=swap: \
+ :pc#1659168:oc#0: \
+ :pd#201600:od#100800:bd#8192:fd#1024:td=4.2BSD: \
+ :pe#20160:oe#1310400:be#8192:fe#1024:te=4.2BSD: \
+ :ph#1008000:oh#302400:bh#8192:fh#1024:th=4.2BSD: \
+ :pg#302400:og#1330560:bg#4096:fg#512:tg=4.2BSD:
+
+fuji513|Fujitsu M22XXXX: \
+ :ty=winchester:dt=ESDI:se#512:nt#16:ns#63:nc#954:rm#3600:\
+ :pa#20160:oa#82656:ba#4096:fa#512:ta=4.2BSD: \
+ :pb#40320:ob#102816:tb=swap: \
+ :pc#961632:oc#0: \
+ :ph#656208:oh#143136:bh#4096:fh#512:th=4.2BSD:
+
+sony650|Sony 650 MB MOD|\
+ :ty=removable:dt=SCSI:se#512:nt#1:ns#31:nc#18600:ts#1:rm#4800:\
+ :pc#576600:oc#0:\
+ :pa#576600:oa#0:ta=4.2BSD:ba#8192:fa#1024:
+
+mta3230|mo230|IBM MTA-3230 230 Meg 3.5inch Magneto-Optical:\
+ :ty=removeable:dt=SCSI:rm#3600:\
+ :se#512:nt#64:ns#32:nc#216:sc#2048:su#444384:\
+ :pa#444384:oa#0:ba#4096:fa#0:ta=4.2BSD:\
+ :pc#444384:oc#0:
+
+minimum:ty=mfs:se#512:nt#1:rm#300:\
+ :ns#2880:nc#1:\
+ :pa#2880:oa#0:ba#4096:fa#512:\
+ :pc#2880:oc#0:bc#4096:fc#512:
+
+minimum2:ty=mfs:se#512:nt#1:rm#300:\
+ :ns#5760:nc#1:\
+ :pa#5760:oa#0:ba#4096:fa#512:\
+ :pc#5760:oc#0:bc#4096:fc#512:
+
+minimum3:ty=mfs:se#512:nt#1:rm#300:\
+ :ns#8640:nc#1:\
+ :pa#8640:oa#0:ba#4096:fa#512:\
+ :pc#8640:oc#0:bc#4096:fc#512:
+
+zip100|zip 100:\
+ :ty=removable:se#512:nc#96:nt#64:ns#32:\
+ :pa#196608:oa#0:ba#4096:fa#512:\
+ :pb#196608:ob#0:bb#4096:fb#512:\
+ :pc#196608:oc#0:bc#4096:fc#512:
+
+zip250|zip 250:\
+ :ty=removable:se#512:nc#239:nt#64:ns#32:\
+ :pa#489472:oa#0:ba#4096:fa#512:\
+ :pb#489472:ob#0:bb#4096:fb#512:\
+ :pc#489472:oc#0:bc#4096:fc#512:
+
+orb2200|orb22|orb:\
+ :ty=removable:ns#63:nt#128:nc#4273:sc#1008:su#4307184:se#512:\
+ :pa#4307184:oa#0:ba#8192:fa#1024:\
+ :pc#4307184:oc#0:bc#8192:fc#1024:
+
diff --git a/etc/fbtab b/etc/fbtab
new file mode 100644
index 0000000..06d2d61
--- /dev/null
+++ b/etc/fbtab
@@ -0,0 +1,4 @@
+# $FreeBSD: src/etc/fbtab,v 1.3 1999/09/13 17:09:07 peter Exp $
+#
+#/dev/ttyv0 0600 /dev/console
+#/dev/ttyv0 0600 /dev/pcaudio:/dev/pcaudioctl
diff --git a/etc/group b/etc/group
new file mode 100644
index 0000000..cac3e1e
--- /dev/null
+++ b/etc/group
@@ -0,0 +1,15 @@
+wheel:*:0:root,admin
+daemon:*:1:daemon
+kmem:*:2:root
+sys:*:3:root
+tty:*:4:root
+operator:*:5:root
+bin:*:7:
+staff:*:20:root
+guest:*:31:root
+dialer:*:68:
+network:*:69:
+www:*:80:
+nogroup:*:65533:
+nobody:*:65534:
+admin:*:101:
diff --git a/etc/host.conf b/etc/host.conf
new file mode 100644
index 0000000..6643c7f
--- /dev/null
+++ b/etc/host.conf
@@ -0,0 +1,7 @@
+# $FreeBSD: src/etc/host.conf,v 1.6 1999/08/27 23:23:41 peter Exp $
+# First try the /etc/hosts file
+hosts
+# Now try the nameserver next.
+bind
+# If you have YP/NIS configured, uncomment the next line
+# nis
diff --git a/etc/hosts.allow b/etc/hosts.allow
new file mode 100644
index 0000000..ab11cc0
--- /dev/null
+++ b/etc/hosts.allow
@@ -0,0 +1,5 @@
+#
+# hosts.allow access control file for "tcp wrapped" applications.
+#
+ALL : ALL : allow
+
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc
new file mode 100644
index 0000000..d5d78b1
--- /dev/null
+++ b/etc/inc/captiveportal.inc
@@ -0,0 +1,642 @@
+<?php
+/*
+ captiveportal.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");
+require_once("radius_accounting.inc") ;
+
+function captiveportal_configure() {
+ global $config, $g;
+
+ if (isset($config['captiveportal']['enable']) &&
+ (($config['captiveportal']['interface'] == "lan") ||
+ isset($config['interfaces'][$config['captiveportal']['interface']]['enable']))) {
+
+ if ($g['booting'])
+ echo "Starting captive portal... ";
+
+ /* kill any running mini_httpd */
+ killbypid("{$g['varrun_path']}/mini_httpd.cp.pid");
+ killbypid("{$g['varrun_path']}/mini_httpd.cps.pid");
+
+ /* kill any running minicron */
+ killbypid("{$g['varrun_path']}/minicron.pid");
+
+ /* generate ipfw rules */
+ $cprules = captiveportal_rules_generate();
+
+ /* make sure ipfw is loaded */
+ mwexec("/sbin/kldload ipfw");
+
+ /* stop accounting on all clients */
+ captiveportal_radius_stop_all() ;
+
+ /* remove old information */
+ unlink_if_exists("{$g['vardb_path']}/captiveportal.nextrule");
+ unlink_if_exists("{$g['vardb_path']}/captiveportal.db");
+ unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db");
+ unlink_if_exists("{$g['vardb_path']}/captiveportal_ip.db");
+ unlink_if_exists("{$g['vardb_path']}/captiveportal_radius.db");
+
+ /* write portal page */
+ if ($config['captiveportal']['page']['htmltext'])
+ $htmltext = base64_decode($config['captiveportal']['page']['htmltext']);
+ else {
+ /* example/template page */
+ $htmltext = <<<EOD
+<html>
+<head>
+<title>m0n0wall captive portal</title>
+</head>
+<body>
+<h2>m0n0wall captive portal</h2>
+<p>This is the default captive portal page. Please upload your own custom HTML file on the <em>Services: Captive portal</em> screen in the m0n0wall webGUI.</p>
+<form method="post" action="">
+ <input name="accept" type="submit" value="Continue">
+</form>
+</body>
+</html>
+
+EOD;
+ }
+
+ $fd = @fopen("{$g['varetc_path']}/captiveportal.html", "w");
+ if ($fd) {
+ fwrite($fd, $htmltext);
+ fclose($fd);
+ }
+
+ /* write error page */
+ if ($config['captiveportal']['page']['errtext'])
+ $errtext = base64_decode($config['captiveportal']['page']['errtext']);
+ else {
+ /* example page */
+ $errtext = <<<EOD
+<html>
+<head>
+<title>Authentication error</title>
+</head>
+<body>
+<font color="#cc0000"><h2>Authentication error</h2></font>
+<b>
+Username and/or password invalid.
+<br><br>
+<a href="javascript:history.back()">Go back</a>
+</b>
+</body>
+</html>
+
+EOD;
+ }
+
+ $fd = @fopen("{$g['varetc_path']}/captiveportal-error.html", "w");
+ if ($fd) {
+ fwrite($fd, $errtext);
+ fclose($fd);
+ }
+
+ /* load rules */
+ mwexec("/sbin/ipfw -f delete set 1");
+ mwexec("/sbin/ipfw -f delete set 2");
+ mwexec("/sbin/ipfw -f delete set 3");
+
+ /* 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.cp.rules", "w");
+ if (!$fd) {
+ printf("Cannot open ipfw.cp.rules in captiveportal_configure()\n");
+ return 1;
+ }
+
+ fwrite($fd, $cprules);
+ fclose($fd);
+
+ mwexec("/sbin/ipfw {$g['tmp_path']}/ipfw.cp.rules");
+
+ unlink("{$g['tmp_path']}/ipfw.cp.rules");
+
+ /* filter on layer2 as well so we can check MAC addresses */
+ mwexec("/sbin/sysctl net.link.ether.ipfw=1");
+
+ chdir($g['captiveportal_path']);
+
+ /* start web server */
+ mwexec("/usr/local/sbin/mini_httpd -a -M 0 -u root -maxproc 16" .
+ " -p 8000 -i {$g['varrun_path']}/mini_httpd.cp.pid");
+
+ /* fire up another one for HTTPS if requested */
+ if (isset($config['captiveportal']['httpslogin']) &&
+ $config['captiveportal']['certificate'] && $config['captiveportal']['private-key']) {
+
+ $cert = base64_decode($config['captiveportal']['certificate']);
+ $key = base64_decode($config['captiveportal']['private-key']);
+
+ $fd = fopen("{$g['varetc_path']}/cert-portal.pem", "w");
+ if (!$fd) {
+ printf("Error: cannot open cert-portal.pem in system_webgui_start().\n");
+ return 1;
+ }
+ chmod("{$g['varetc_path']}/cert-portal.pem", 0600);
+ fwrite($fd, $cert);
+ fwrite($fd, "\n");
+ fwrite($fd, $key);
+ fclose($fd);
+
+ mwexec("/usr/local/sbin/mini_httpd -S -a -M 0 -E {$g['varetc_path']}/cert-portal.pem" .
+ " -u root -maxproc 16 -p 8001" .
+ " -i {$g['varrun_path']}/mini_httpd.cps.pid");
+ }
+
+ /* start pruning process (interval = 60 seconds) */
+ mwexec("/usr/local/bin/minicron 60 {$g['varrun_path']}/minicron.pid " .
+ "/etc/rc.prunecaptiveportal");
+
+ /* generate passthru mac database */
+ captiveportal_passthrumac_configure() ;
+ /* create allowed ip database and insert ipfw rules to make it so */
+ captiveportal_allowedip_configure() ;
+
+ /* generate radius server database */
+ if($config['captiveportal']['radiusip']) {
+ $radiusip = $config['captiveportal']['radiusip'] ;
+
+ if($config['captiveportal']['radiusport'])
+ $radiusport = $config['captiveportal']['radiusport'] ;
+ else
+ $radiusport = 1812;
+
+ if($config['captiveportal']['radiusacctport'])
+ $radiusacctport = $config['captiveportal']['radiusacctport'] ;
+ else
+ $radiusacctport = 1813;
+
+ $radiuskey = $config['captiveportal']['radiuskey'];
+
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db", "w");
+ if (!$fd) {
+ printf("Error: cannot open radius DB file in captiveportal_configure().\n");
+ return 1;
+ } else {
+ fwrite($fd,$radiusip . "," . $radiusport . "," . $radiusacctport . "," . $radiuskey) ;
+ }
+ fclose($fd) ;
+ }
+
+
+ if ($g['booting'])
+ echo "done\n";
+
+ } else {
+ killbypid("{$g['varrun_path']}/mini_httpd.cp.pid");
+ killbypid("{$g['varrun_path']}/minicron.pid");
+ captiveportal_radius_stop_all() ;
+ mwexec("/sbin/sysctl net.link.ether.ipfw=0");
+ if (!isset($config['shaper']['enable'])) {
+ /* unload ipfw */
+ mwexec("/sbin/kldunload ipfw");
+ } else {
+ /* shaper is on - just remove our rules */
+ mwexec("/sbin/ipfw -f delete set 1");
+ mwexec("/sbin/ipfw -f delete set 2");
+ mwexec("/sbin/ipfw -f delete set 3");
+ }
+ }
+
+ return 0;
+}
+
+function captiveportal_rules_generate() {
+ global $config, $g;
+
+ $cpifn = $config['captiveportal']['interface'];
+ $cpif = $config['interfaces'][$cpifn]['if'];
+ $cpip = $config['interfaces'][$cpifn]['ipaddr'];
+
+ /* note: the captive portal daemon inserts all pass rules for authenticated
+ clients as skipto 50000 rules to make traffic shaping work */
+
+ $cprules = "";
+
+ /* captive portal on LAN interface? */
+ if ($cpifn == "lan") {
+ /* add anti-lockout rules */
+ $cprules .= <<<EOD
+add 500 set 1 pass all from $cpip to any out via $cpif
+add 501 set 1 pass all from any to $cpip in via $cpif
+
+EOD;
+ }
+
+ $cprules .= <<<EOD
+# skip to traffic shaper if not on captive portal interface
+add 1000 set 1 skipto 50000 all from any to any not layer2 not via $cpif
+# pass all layer2 traffic on other interfaces
+add 1001 set 1 pass layer2 not via $cpif
+
+# layer 2: pass ARP
+add 1100 set 1 pass layer2 mac-type arp
+# layer 2: block anything else non-IP
+add 1101 set 1 deny layer2 not mac-type ip
+# layer 2: check if MAC addresses of authenticated clients are correct
+add 1102 set 1 skipto 20000 layer2
+
+# allow access to our DHCP server (which needs to be able to ping clients as well)
+add 1200 set 1 pass udp from any 68 to 255.255.255.255 67 in
+add 1201 set 1 pass udp from any 68 to $cpip 67 in
+add 1202 set 1 pass udp from $cpip 67 to any 68 out
+add 1203 set 1 pass icmp from $cpip to any out icmptype 8
+add 1204 set 1 pass icmp from any to $cpip in icmptype 0
+
+# allow access to our DNS forwarder
+add 1300 set 1 pass udp from any to $cpip 53 in
+add 1301 set 1 pass udp from $cpip 53 to any out
+
+# allow access to our web server
+add 1302 set 1 pass tcp from any to $cpip 8000 in
+add 1303 set 1 pass tcp from $cpip 8000 to any out
+
+EOD;
+
+ if (isset($config['captiveportal']['httpslogin'])) {
+ $cprules .= <<<EOD
+add 1304 set 1 pass tcp from any to $cpip 8001 in
+add 1305 set 1 pass tcp from $cpip 8001 to any out
+
+EOD;
+ }
+
+ $cprules .= <<<EOD
+
+# ... 10000-19899: rules per authenticated client go here...
+
+# redirect non-authenticated clients to captive portal
+add 19900 set 1 fwd 127.0.0.1,8000 tcp from any to any 80 in
+# let the responses from the captive portal web server back out
+add 19901 set 1 pass tcp from any 80 to any out
+# block everything else
+add 19902 set 1 deny all from any to any
+
+# ... 20000-29899: layer2 block rules per authenticated client go here...
+
+# pass everything else on layer2
+add 29900 set 1 pass all from any to any layer2
+
+EOD;
+
+ return $cprules;
+}
+
+/* remove clients that have been around for longer than the specified amount of time */
+/* db file structure: timestamp,ipfw_rule_no,clientip,clientmac,username,sessionid */
+function captiveportal_prune_old() {
+
+ global $g, $config;
+
+ /* check for expired entries */
+ if ($config['captiveportal']['timeout'])
+ $timeout = $config['captiveportal']['timeout'] * 60;
+ else
+ $timeout = 0;
+
+ if ($config['captiveportal']['idletimeout'])
+ $idletimeout = $config['captiveportal']['idletimeout'] * 60;
+ else
+ $idletimeout = 0;
+
+ if (!$timeout && !$idletimeout)
+ return;
+
+ captiveportal_lock();
+
+ /* read database */
+ $cpdb = captiveportal_read_db();
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ for ($i = 0; $i < count($cpdb); $i++) {
+
+ $timedout = false;
+
+ /* hard timeout? */
+ if ($timeout) {
+ if ((time() - $cpdb[$i][0]) >= $timeout)
+ $timedout = true;
+ }
+
+ /* if an idle timeout is specified, get last activity timestamp from ipfw */
+ if (!$timedout && $idletimeout) {
+ $lastact = captiveportal_get_last_activity($cpdb[$i][1]);
+ if ($lastact && ((time() - $lastact) >= $idletimeout))
+ $timedout = true;
+ }
+
+ if ($timedout) {
+ /* this client needs to be deleted - remove ipfw rules */
+ if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $cpdb[$i][0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ unset($cpdb[$i]);
+ }
+ }
+
+ /* write database */
+ captiveportal_write_db($cpdb);
+
+ captiveportal_unlock();
+}
+
+/* remove a single client by ipfw rule number */
+function captiveportal_disconnect_client($id) {
+
+ global $g, $config;
+
+ captiveportal_lock();
+
+ /* read database */
+ $cpdb = captiveportal_read_db();
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* find entry */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ if ($cpdb[$i][1] == $id) {
+ /* this client needs to be deleted - remove ipfw rules */
+ if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $cpdb[$i][0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+
+ /* write database */
+ captiveportal_write_db($cpdb);
+
+ captiveportal_unlock();
+}
+
+/* send RADIUS acct stop for all current clients */
+function captiveportal_radius_stop_all() {
+ global $g, $config;
+
+ captiveportal_lock() ;
+ $cpdb = captiveportal_read_db() ;
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ if (isset($radiusservers[0])) {
+ for ($i = 0; $i < count($cpdb); $i++) {
+ RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $cpdb[$i][0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ }
+ captiveportal_unlock() ;
+}
+
+function captiveportal_passthrumac_configure() {
+ global $config, $g;
+
+ /* clear out passthru macs, if necessary */
+ if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) {
+ unlink("{$g['vardb_path']}/captiveportal_mac.db");
+ }
+
+ if (is_array($config['captiveportal']['passthrumac'])) {
+
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db", "w");
+ if (!$fd) {
+ printf("Error: cannot open passthru mac DB file in captiveportal_passthrumac_configure().\n");
+ return 1;
+ }
+
+ foreach ($config['captiveportal']['passthrumac'] as $macent) {
+ /* record passthru mac so it can be recognized and let thru */
+ fwrite($fd, $macent['mac'] . "\n");
+ }
+
+ fclose($fd);
+ }
+
+ return 0;
+}
+
+function captiveportal_allowedip_configure() {
+ global $config, $g;
+
+ captiveportal_lock() ;
+
+ /* clear out existing allowed ips, if necessary */
+ if (file_exists("{$g['vardb_path']}/captiveportal_ip.db")) {
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "r");
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = trim(fgets($fd));
+ if($line) {
+ list($ip,$rule) = explode(",",$line);
+ mwexec("/sbin/ipfw delete $rule") ;
+ }
+ }
+ }
+ fclose($fd) ;
+ unlink("{$g['vardb_path']}/captiveportal_ip.db");
+ }
+
+ /* get next ipfw rule number */
+ if (file_exists("{$g['vardb_path']}/captiveportal.nextrule"))
+ $ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule"));
+ if (!$ruleno)
+ $ruleno = 10000; /* first rule number */
+
+ if (is_array($config['captiveportal']['allowedip'])) {
+
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_ip.db", "w");
+ if (!$fd) {
+ printf("Error: cannot open allowed ip DB file in captiveportal_allowedip_configure().\n");
+ captiveportal_unlock() ;
+ return 1;
+ }
+
+ foreach ($config['captiveportal']['allowedip'] as $ipent) {
+ /* record allowed ip so it can be recognized and removed later */
+ fwrite($fd, $ipent['ip'] . "," . $ruleno ."\n");
+ /* insert ipfw rule to allow ip thru */
+ if($ipent['dir'] == "from") {
+ mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from ".$ipent['ip']." to any in") ;
+ mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to ".$ipent['ip']." out") ;
+ } else {
+ mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to ".$ipent['ip']." in") ;
+ mwexec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from ".$ipent['ip']." to any out") ;
+ }
+ $ruleno++ ;
+ if ($ruleno > 19899)
+ $ruleno = 10000;
+ }
+
+ fclose($fd);
+
+ /* write next rule number */
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w");
+ if ($fd) {
+ fwrite($fd, $ruleno);
+ fclose($fd);
+ }
+ }
+
+ captiveportal_unlock() ;
+ return 0;
+}
+
+/* get last activity timestamp given ipfw rule number */
+function captiveportal_get_last_activity($ruleno) {
+
+ exec("/sbin/ipfw -T list {$ruleno} 2>/dev/null", $ipfwoutput);
+
+ /* in */
+ if ($ipfwoutput[0]) {
+ $ri = explode(" ", $ipfwoutput[0]);
+ if ($ri[1])
+ return $ri[1];
+ }
+
+ return 0;
+}
+
+/* read captive portal DB into array */
+function captiveportal_read_db() {
+
+ global $g;
+
+ $cpdb = array();
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = trim(fgets($fd));
+ if ($line) {
+ $cpdb[] = explode(",", $line);
+ }
+ }
+ fclose($fd);
+ }
+ return $cpdb;
+}
+
+/* write captive portal DB */
+function captiveportal_write_db($cpdb) {
+
+ global $g;
+
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
+ if ($fd) {
+ foreach ($cpdb as $cpent) {
+ fwrite($fd, join(",", $cpent) . "\n");
+ }
+ fclose($fd);
+ }
+}
+
+/* read RADIUS servers into array */
+function captiveportal_get_radius_servers() {
+
+ global $g;
+
+ if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r");
+ if ($fd) {
+ $radiusservers = array();
+ while (!feof($fd)) {
+ $line = trim(fgets($fd));
+ if ($line) {
+ $radsrv = array();
+ list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line);
+ $radiusservers[] = $radsrv;
+ }
+ }
+ fclose($fd);
+
+ return $radiusservers;
+ }
+ }
+
+ return false;
+}
+
+/* lock captive portal information, decide that the lock file is stale after
+ 10 seconds */
+function captiveportal_lock() {
+
+ global $g;
+
+ $lockfile = "{$g['varrun_path']}/captiveportal.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 captiveportal_unlock() {
+
+ global $g;
+
+ $lockfile = "{$g['varrun_path']}/captiveportal.lock";
+
+ if (file_exists($lockfile))
+ unlink($lockfile);
+}
+
+?>
diff --git a/etc/inc/config.inc b/etc/inc/config.inc
new file mode 100644
index 0000000..58202aa
--- /dev/null
+++ b/etc/inc/config.inc
@@ -0,0 +1,551 @@
+<?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 kernel known disks until we find one with config.xml */
+ $disks = explode(" ", trim(preg_replace("/kern.disks: /", "", exec("/sbin/sysctl kern.disks"))));
+ foreach ($disks as $mountdisk) {
+ /* skip mfs mounted filesystems */
+ if (strstr($mountdisk, "md"))
+ continue;
+ if (mwexec("/sbin/mount -r /dev/{$mountdisk}a {$g['cf_path']}") == 0) {
+ if (file_exists("{$g['cf_conf_path']}/config.xml")) {
+ /* found it */
+ $cfgdevice = $mountdisk;
+ $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['pfqueueing']['rule']);
+ if (is_array($config['pfqueueing']['rule']))
+ for ($i = 0; $i < $n; $i++) {
+
+ $fr = &$config['pfqueueing']['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['pfqueueing']['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['pfqueueing']['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['pfqueueing']['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['pfqueueing']['rule'])) {
+ $config['pfqueueing']['pipe'] = array();
+
+ for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
+ $curent = &$config['pfqueueing']['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['pfqueueing']['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();
+
+ if (time() > mktime(0, 0, 0, 9, 1, 2004)) /* make sure the clock settings is plausible */
+ $config['lastchange'] = time();
+
+ /* 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/etc/inc/filter.inc b/etc/inc/filter.inc
new file mode 100644
index 0000000..1b409f8
--- /dev/null
+++ b/etc/inc/filter.inc
@@ -0,0 +1,946 @@
+<?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/pfctl -y"); /* XXX */
+}
+
+function filter_ipmon_start() {
+ global $config, $g;
+
+ mwexec("/pflogd -sD");
+}
+
+function filter_configure() {
+ global $config, $g;
+
+ if ($g['booting'])
+ echo "Configuring firewall... ";
+
+ /* set TCP timeouts */
+ $tcpidletimeout = 9000;
+ if ($config['filter']['tcpidletimeout'])
+ $tcpidletimeout = $config['filter']['tcpidletimeout'];
+ mwexec("/sbin/sysctl net.inet.ipf.fr_tcpidletimeout={$tcpidletimeout}");
+ mwexec("/sbin/sysctl net.inet.ipf.fr_tcphalfclosed=480");
+
+ /* generate pfctl rules */
+ $natrules = filter_nat_rules_generate();
+ /* generate pfctl rules */
+ $pfrules = filter_rules_generate();
+ /* generate altq interface setup parms */
+ $altq_ints = filter_setup_altq_interfaces();
+ /* generate altq queues */
+ $altq_queues = filter_generate_altq_queues();
+
+ mwexec("/sbin/pfctl -e");
+ mwexec("/sbin/pfctl -F nat");
+ mwexec("/sbin/pfctl -F rules");
+
+ /* get our wan interface? */
+ $wanif = get_real_wan_interface();
+
+ $fd = fopen("/tmp/rules.debug", "w");
+ fwrite($fd, "set loginterface $wanif \n");
+ fwrite($fd, "set optimization aggressive\n");
+ fwrite($fd, $altq_ints);
+ fwrite($fd, $altq_queues);
+ fwrite($fd, $natrules);
+ fwrite($fd, $pfrules);
+ fclose($fd);
+
+ mwexec("chmod a+x /tmp/rules.debug");
+ mwexec("/sbin/pfctl -f /tmp/rules.debug");
+
+ /* set up MSS clamping */
+ if ($config['interfaces']['wan']['mtu'])
+ $mssclamp = $config['interfaces']['wan']['mtu'] - 40;
+ else if ($config['interfaces']['wan']['ipaddr'] == "pppoe")
+ $mssclamp = 1452;
+ else
+ $mssclamp = 0;
+
+ mwexec("/sbin/sysctl net.inet.ipf.fr_mssif={$wanif}");
+ mwexec("/sbin/sysctl net.inet.ipf.fr_mssclamp={$mssclamp}");
+
+ if ($g['booting'])
+ echo "done\n";
+
+ return 0;
+}
+
+function filter_generate_altq_queues() {
+ global $config;
+ $altq_rules = "";
+ if (is_array($config['pfqueueing']['queue'])) {
+ foreach ($config['pfqueueing']['queue'] as $rule) {
+ $altq_rules .= "queue " . $rule['name'] . " ";
+ if (isset($rule['bandwidth']))
+ $altq_rules .= "bandwidth " . $rule['bandwidth'] . " ";
+ if (isset($rule['priority']))
+ $altq_rules .= "priority " . $rule['priority'] . " ";
+ if (isset($rule['options'])) /* XXX turn options into an xml array */
+ $altq_rules .= $rule['schedulertype'] . "(". $rule['options'] . ")";
+ if (isset($rule['subqueue'])) {
+ $altq_rules .= "{ ";
+ $fsq = "";
+ foreach ($rule['subqueue'] as $sq) {
+ if($fsq) $altq_rules .= ",";
+ $altq_rules .= $sq['name'];
+ $fsq = "1";
+ }
+ $altq_rules .= " }";
+ }
+ $altq_rules .= "\n";
+ }
+ }
+ return $altq_rules;
+}
+
+function filter_setup_altq_interfaces() {
+ global $config;
+ $altq_rules = "";
+ $queue_names = "";
+ $is_first = "";
+ if (is_array($config['pfqueueing']['queue'])) {
+ foreach ($config['pfqueueing']['queue'] as $queue) {
+ if(is_subqueue($queue['name']) == 0) {
+ if($is_first) $queue_names .= ", ";
+ $queue_names .= $queue['name'];
+ $is_first = "1";
+ }
+ }
+ }
+ if (is_array($config['interfaces'])) {
+ foreach ($config['interfaces'] as $ifname) {
+ if(isset($ifname['bandwidth'])) {
+ $subnet = $ifname['ipaddr'] . "/" . $ifname['subnet'];
+ $altq_rules .= "altq on " . $ifname['if'] . " ";
+ $altq_rules .= $ifname['schedulertype'] . " bandwidth " . $ifname['bandwidth'] . " ";
+ if($queue_names <> "")
+ $altq_rules .= "queue { " . $queue_names . " }";
+ $altq_rules .= "\n";
+ }
+ }
+ }
+ return $altq_rules;
+}
+
+function is_subqueue($name) {
+ global $config;
+ $status = "";
+ if (is_array($config['pfqueueing']['queue'])) {
+ foreach ($config['pfqueueing']['queue'] as $queue) {
+ if(is_array($queue['subqueue'])) {
+ foreach ($queue['subqueue'] as $sq) {
+ if($sq['name'] == $name) return 1;
+ }
+ }
+ }
+ }
+ return 0;
+}
+
+function filter_flush_nat_table() {
+ global $config, $g;
+
+ return mwexec("/sbin/pfctl -F nat");
+}
+
+function filter_flush_state_table() {
+ global $config, $g;
+
+ return mwexec("/sbin/pfctl -F state");
+}
+
+function filter_nat_rules_generate_if($if, $src, $dst, $target) {
+
+ if ($target)
+ $tgt = $target . "/32";
+ else
+ $tgt = "0/32";
+
+ $natrule = <<<EOD
+nat on $if from $src to any -> $if
+
+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();
+
+ $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'];
+
+ if (!$natent['interface'] || ($natent['interface'] == "wan"))
+ $natif = $wanif;
+ else
+ $natif = $config['interfaces'][$natent['interface']]['if'];
+
+ $natrules .= "binat on {$natif} from {$natent['internal']}/{$sn} to any -> {$natent['external']}\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'];
+
+ if (!$obent['interface'] || ($obent['interface'] == "wan"))
+ $natif = $wanif;
+ else
+ $natif = $config['interfaces'][$obent['interface']]['if'];
+
+ $natrules .= filter_nat_rules_generate_if($natif, $src, $dst,
+ $obent['target']);
+ }
+ }
+ } else {
+ /* standard outbound rules (one for each interface) */
+ $natrules .= filter_nat_rules_generate_if($wanif,
+ $lansa . "/" . $lancfg['subnet'], "", null);
+
+ /* optional interfaces */
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $optcfg = $config['interfaces']['opt' . $i];
+
+ if (isset($optcfg['enable']) && !$optcfg['bridge']) {
+ $optsa = gen_subnet($optcfg['ipaddr'], $optcfg['subnet']);
+ $natrules .= filter_nat_rules_generate_if($wanif,
+ $optsa . "/" . $optcfg['subnet'], "", null);
+ }
+ }
+
+ /* PPTP subnet */
+ if ($pptpdcfg['mode'] == "server") {
+ $natrules .= filter_nat_rules_generate_if($wanif,
+ $pptpdcfg['remoteip'] . "/" . $g['pptp_subnet'], "", null);
+ }
+
+ /* static routes */
+ if (is_array($config['staticroutes']['route'])) {
+ foreach ($config['staticroutes']['route'] as $route) {
+ if ($route['interface'] != "wan")
+ $natrules .= filter_nat_rules_generate_if($wanif,
+ $route['network'], "", null);
+ }
+ }
+ }
+
+ /* DIAG: add ipv6 NAT, if requested */
+ if (isset($config['diag']['ipv6nat']['enable'])) {
+ $natrules .= "rdr on $wanif proto ipv6 from any to any port 0 -> " .
+ "{$config['diag']['ipv6nat']['ipaddr']}\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 (!$rule['interface'] || ($rule['interface'] == "wan"))
+ $natif = $wanif;
+ else
+ $natif = $config['interfaces'][$rule['interface']]['if'];
+
+ $lanif = $lancfg['if'];
+
+ if ((!$extport[1]) || ($extport[0] == $extport[1])) {
+ $natrules .=
+ "rdr on $natif proto " . $rule['protocol'] . " from any to any port {$extport[0]} -> {$target} \n";
+ } else {
+ $natrules .=
+ "rdr on $natif proto " . $rule['protocol']. " from any to any port {$extport[0]}:{$extport[1]} " .
+ "-> {$target} \n";
+ }
+
+ $natrules .= "\n";
+ }
+ }
+
+ if ($pptpdcfg['mode'] && $pptpdcfg['mode'] != "off") {
+
+ if ($pptpdcfg['mode'] == "server")
+ $pptpdtarget = "127.0.0.1";
+ else if ($pptpdcfg['mode'] == "redir")
+ $pptpdtarget = $pptpdcfg['redir'];
+
+ if ($pptpdtarget) {
+
+ $natrules .= <<<EOD
+
+# PPTP
+rdr on $wanif proto gre from any to any port 0 -> $pptpdtarget
+rdr on $wanif proto tcp from any to any port 1723 -> $pptpdtarget
+
+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']) {
+ if (!strstr($oc['bridge'], "opt") ||
+ isset($config['interfaces'][$oc['bridge']]['enable'])) {
+ if (is_ipaddr($config['interfaces'][$oc['bridge']]['ipaddr'])) {
+ $oic['ip'] = $config['interfaces'][$oc['bridge']]['ipaddr'];
+ $oic['sn'] = $config['interfaces'][$oc['bridge']]['subnet'];
+ $oic['sa'] = gen_subnet($oic['ip'], $oic['sn']);
+ }
+ }
+ $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
+
+# 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']) && (!$oc['bridge'])) {
+ $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;
+ }
+ }
+
+ /* pass traffic between statically routed subnets and the subnet on the
+ interface in question to avoid problems with complicated routing
+ topologies */
+ if (is_array($config['staticroutes']['route']) && count($config['staticroutes']['route'])) {
+ foreach ($config['staticroutes']['route'] as $route) {
+ unset($sa);
+
+ if ($route['interface'] == "lan") {
+ $sa = $lansa;
+ $sn = $lansn;
+ $if = $lanif;
+ } else if (strstr($route['interface'], "opt")) {
+ $oc = $optcfg[$route['interface']];
+ if ($oc['ip']) {
+ $sa = $oc['sa'];
+ $sn = $oc['sn'];
+ $if = $oc['if'];
+ }
+ }
+
+ if ($sa) {
+ $ipfrules .= <<<EOD
+pass in quick on {$if} from {$sa}/{$sn} to {$route['network']}
+pass in quick on {$if} from {$route['network']} to {$sa}/{$sn}
+pass out quick on {$if} from {$sa}/{$sn} to {$route['network']}
+pass out quick on {$if} from {$route['network']} to {$sa}/{$sn}
+
+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) {
+ if ($oc['ip'])
+ $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) {
+ if ($oc['ip'])
+ $ipfrules .= filter_rules_ipsec_generate($oc['if'], $oc['ip']);
+ }
+ }
+
+ /* XXX - the first section is only needed because pfctl 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
+
+
+# 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
+
+
+# let out anything from the firewall host itself and decrypted IPsec traffic
+pass out quick on {$oc['if']} all keep state
+
+EOD;
+
+ }
+
+ if (!isset($config['system']['webgui']['noantilockout'])) {
+
+ $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;
+ }
+
+ /* BigPond client enabled? */
+ if ($wancfg['ipaddr'] == "bigpond") {
+
+ $ipfrules .= <<<EOD
+
+# BigPond heartbeat rules
+pass in quick proto udp from any to any port = 5050 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") {
+ $i++;
+ continue;
+ }
+
+ $nif = $g['n_pptp_units'];
+ $ispptp = true;
+ } else {
+
+ if (strstr($rule['interface'], "opt")) {
+ if (!array_key_exists($rule['interface'], $optcfg)) {
+ $i++;
+ continue;
+ }
+ }
+
+ $nif = 1;
+ $ispptp = false;
+ }
+
+ if ($pptpdcfg['mode'] != "server") {
+ if (($rule['source']['network'] == "pptp") ||
+ ($rule['destination']['network'] == "pptp")) {
+ $i++;
+ continue;
+ }
+ }
+
+ if ($rule['source']['network'] && strstr($rule['source']['network'], "opt")) {
+ if (!array_key_exists($rule['source']['network'], $optcfg)) {
+ $i++;
+ continue;
+ }
+ }
+ if ($rule['destination']['network'] && strstr($rule['destination']['network'], "opt")) {
+ if (!array_key_exists($rule['destination']['network'], $optcfg)) {
+ $i++;
+ continue;
+ }
+ }
+
+ /* check for unresolvable aliases */
+ if ($rule['source']['address'] && !alias_expand($rule['source']['address'])) {
+ $i++;
+ continue;
+ }
+ if ($rule['destination']['address'] && !alias_expand($rule['destination']['address'])) {
+ $i++;
+ 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;
+ }
+
+ if(!isset($rule['direction'])) {
+ $line .= " in ";
+ } else {
+ $line .= " " . $rule['direction'] . " ";
+ }
+
+ 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 || ($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 || ($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 (($rule['protocol'] == "icmp") && $rule['icmptype']) {
+ $line .= "icmp-type {$rule['icmptype']} ";
+ }
+
+ 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 (isset($rule['flags'])) {
+ $line .= "flags " . $rule['flags'] . " ";
+ }
+
+ if (!$ispptp) {
+ #$line .= "group $groupnum ";
+ }
+
+ if (isset($rule['queuename'])) {
+ $line .= "queue " . $rule['queuename'];
+ }
+
+ $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/etc/inc/functions.inc b/etc/inc/functions.inc
new file mode 100644
index 0000000..eab4b82
--- /dev/null
+++ b/etc/inc/functions.inc
@@ -0,0 +1,41 @@
+<?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");
+require_once("captiveportal.inc");
+require_once("openvpn.inc");
+
+?>
diff --git a/etc/inc/globals.inc b/etc/inc/globals.inc
new file mode 100644
index 0000000..eef6cff
--- /dev/null
+++ b/etc/inc/globals.inc
@@ -0,0 +1,54 @@
+<?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",
+ "varlog_path" => "/var/log",
+ "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",
+ "captiveportal_path" => "/usr/local/captiveportal",
+ "xml_rootobj" => "m0n0wall",
+ "pppoe_interface" => "ng0",
+ "n_pptp_units" => 16,
+ "pptp_subnet" => 28,
+ "debug" => false,
+ "latest_config" => "1.4",
+ "nopccard_platforms" => array("wrap", "net48xx")
+);
+
+?>
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc
new file mode 100644
index 0000000..00331c1
--- /dev/null
+++ b/etc/inc/interfaces.inc
@@ -0,0 +1,740 @@
+<?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_vlan_configure() {
+ global $config, $g;
+
+ if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
+
+ /* load the VLAN module */
+ mwexec("/sbin/kldload if_vlan");
+
+ /* devices with native VLAN support */
+ $vlan_native_supp = explode(" ", "bge em gx nge ti txp");
+
+ /* devices with long frame support */
+ $vlan_long_supp = explode(" ", "dc fxp sis ste tl tx xl");
+
+ $i = 0;
+
+ foreach ($config['vlans']['vlan'] as $vlan) {
+
+ $cmd = "/sbin/ifconfig vlan{$i} create vlan " .
+ escapeshellarg($vlan['tag']) . " vlandev " .
+ escapeshellarg($vlan['if']);
+
+ /* get driver name */
+ for ($j = 0; $j < strlen($vlan['if']); $j++) {
+ if ($vlan['if'][$j] >= '0' && $vlan['if'][$j] <= '9')
+ break;
+ }
+ $drvname = substr($vlan['if'], 0, $j);
+
+ if (in_array($drvname, $vlan_native_supp))
+ $cmd .= " link0";
+ else if (in_array($drvname, $vlan_long_supp))
+ $cmd .= " mtu 1500";
+
+ mwexec($cmd);
+
+ /* make sure the parent interface is up */
+ mwexec("/sbin/ifconfig " . escapeshellarg($vlan['if']) . " up");
+
+ $i++;
+ }
+ }
+
+ 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']));
+
+ /* media */
+ if ($lancfg['media'] || $lancfg['mediaopt']) {
+ $cmd = "/sbin/ifconfig " . escapeshellarg($lancfg['if']);
+ if ($lancfg['media'])
+ $cmd .= " media " . escapeshellarg($lancfg['media']);
+ if ($lancfg['mediaopt'])
+ $cmd .= " mediaopt " . escapeshellarg($lancfg['mediaopt']);
+ mwexec($cmd);
+ }
+
+ 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();
+
+ /* reload captive portal */
+ captiveportal_configure();
+ }
+
+ 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']));
+
+ /* media */
+ if ($optcfg['media'] || $optcfg['mediaopt']) {
+ $cmd = "/sbin/ifconfig " . escapeshellarg($optcfg['if']);
+ if ($optcfg['media'])
+ $cmd .= " media " . escapeshellarg($optcfg['media']);
+ if ($optcfg['mediaopt'])
+ $cmd .= " mediaopt " . escapeshellarg($optcfg['mediaopt']);
+ mwexec($cmd);
+ }
+
+ /* OpenVPN configuration? */
+ if (isset($optcfg['ovpn'])) {
+ if (strstr($if, "tap"))
+ ovpn_link_tap();
+ }
+
+ /* 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 wanip, if it exists */
+ if (file_exists("{$g['vardb_path']}/wanip")) {
+ unlink("{$g['vardb_path']}/wanip");
+ }
+ }
+
+ /* 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']));
+
+ /* media */
+ if ($wancfg['media'] || $wancfg['mediaopt']) {
+ $cmd = "/sbin/ifconfig " . escapeshellarg($wancfg['if']);
+ if ($wancfg['media'])
+ $cmd .= " media " . escapeshellarg($wancfg['media']);
+ if ($wancfg['mediaopt'])
+ $cmd .= " mediaopt " . escapeshellarg($wancfg['mediaopt']);
+ mwexec($cmd);
+ }
+
+ switch ($wancfg['ipaddr']) {
+
+ case 'dhcp':
+ interfaces_wan_dhcp_configure();
+ break;
+
+ case 'pppoe':
+ interfaces_wan_pppoe_configure();
+ break;
+
+ case 'pptp':
+ interfaces_wan_pptp_configure();
+ break;
+
+ case 'bigpond':
+ /* just configure DHCP for now; fire up bpalogin when we've got the lease */
+ interfaces_wan_dhcp_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;
+ }
+
+ $idle = 0;
+
+ if (isset($pppoecfg['ondemand'])) {
+ $ondemand = "enable";
+ if ($pppoecfg['timeout'])
+ $idle = $pppoecfg['timeout'];
+ } else {
+ $ondemand = "disable";
+ }
+
+ $mpdconf = <<<EOD
+pppoe:
+ new -i ng0 pppoe pppoe
+ set iface route default
+ set iface {$ondemand} on-demand
+ set iface idle {$idle}
+ set iface up-script /usr/local/sbin/ppp-linkup
+
+EOD;
+
+ if (isset($pppoecfg['ondemand'])) {
+ $mpdconf .= <<<EOD
+ set iface addrs 10.0.0.1 10.0.0.2
+
+EOD;
+ }
+
+ $mpdconf .= <<<EOD
+ 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
+ set ipcp enable req-pri-dns
+ set ipcp enable req-sec-dns
+ 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']}"
+ set pppoe enable originate
+ set pppoe disable incoming
+
+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;
+ }
+
+ $idle = 0;
+
+ if (isset($pptpcfg['ondemand'])) {
+ $ondemand = "enable";
+ if ($pptpcfg['timeout'])
+ $idle = $pptpcfg['timeout'];
+ } else {
+ $ondemand = "disable";
+ }
+
+ $mpdconf = <<<EOD
+pptp:
+ new -i ng0 pptp pptp
+ set iface route default
+ set iface {$ondemand} on-demand
+ set iface idle {$idle}
+ set iface up-script /usr/local/sbin/ppp-linkup
+
+EOD;
+
+ if (isset($pptpcfg['ondemand'])) {
+ $mpdconf .= <<<EOD
+ set iface addrs {$pptpcfg['local']} {$pptpcfg['remote']}
+
+EOD;
+ }
+
+ $mpdconf .= <<<EOD
+ 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
+ set ipcp enable req-pri-dns
+ set ipcp enable req-sec-dns
+ 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 enable originate outcall
+ set pptp disable windowing
+ 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 interfaces_wan_bigpond_configure($curwanip) {
+ global $config, $g;
+
+ $bpcfg = $config['bigpond'];
+
+ if (!$curwanip) {
+ /* IP address not configured yet, exit */
+ return 0;
+ }
+
+ /* kill bpalogin */
+ killbyname("bpalogin");
+
+ /* wait a moment */
+ sleep(1);
+
+ /* get the default domain */
+ $nfd = @fopen("{$g['varetc_path']}/defaultdomain.conf", "r");
+ if ($nfd) {
+ $defaultdomain = trim(fgets($nfd));
+ fclose($nfd);
+ }
+
+ /* generate bpalogin.conf */
+ $fd = fopen("{$g['varetc_path']}/bpalogin.conf", "w");
+ if (!$fd) {
+ printf("Error: cannot open bpalogin.conf in interfaces_wan_bigpond_configure().\n");
+ return 1;
+ }
+
+ if (!$bpcfg['authserver'])
+ $bpcfg['authserver'] = "dce-server";
+ if (!$bpcfg['authdomain'])
+ $bpcfg['authdomain'] = $defaultdomain;
+
+ $bpconf = <<<EOD
+username {$bpcfg['username']}
+password {$bpcfg['password']}
+authserver {$bpcfg['authserver']}
+authdomain {$bpcfg['authdomain']}
+localport 5050
+
+EOD;
+
+ if ($bpcfg['minheartbeatinterval'])
+ $bpconf .= "minheartbeatinterval {$bpcfg['minheartbeatinterval']}\n";
+
+ fwrite($fd, $bpconf);
+ fclose($fd);
+
+ /* fire up bpalogin */
+ mwexec("/usr/local/sbin/bpalogin -c {$g['varetc_path']}/bpalogin.conf");
+
+ 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','bigpond'))) {
+ /* 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/etc/inc/openvpn.inc b/etc/inc/openvpn.inc
new file mode 100644
index 0000000..2414ae0
--- /dev/null
+++ b/etc/inc/openvpn.inc
@@ -0,0 +1,559 @@
+<?php
+/*
+ openvpn.inc
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ 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("globals.inc");
+require_once("config.inc");
+require_once("functions.inc");
+
+function ovpn_configure() {
+ global $config;
+ if (is_array($config['ovpn']['server']))
+ ovpn_config_server();
+ if (is_array($config['ovpn']['client']))
+ ovpn_config_client();
+ return;
+}
+
+function ovpn_link_tap() {
+ /* Add a reference to the tap KLM. If ref count = 1, load it */
+ global $g;
+
+ if (!is_file($g['vardb_path'] ."/ovpn_tap_link")){
+ $link_count = 1;
+ mwexec("/sbin/kldload if_tap");
+ $fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'w');
+ }
+ else {
+ $fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
+ $link_count = fread($fd);
+ $link_count ++;
+ }
+ fwrite($fd, $link_count);
+ fclose($fd);
+ return true;
+}
+
+function ovpn_unlink_tap() {
+ /* Remove a reference to the tap KLM. If ref count = 0, unload it */
+ global $g;
+
+ if (!is_file($g['vardb_path'] ."/ovpn_tap_link"))
+ return false; //no file, no links so why are we called?
+
+ $fd = fopen($g['vardb_path'] ."/ovpn_tap_link", 'r+');
+ $link_count = fread($fd);
+ $link_count --;
+ fwrite($fd, $link_count);
+ fclose($fd);
+
+ if ($link_count == 0)
+ mwexec("/sbin/kldunload if_tap");
+ return true;
+}
+
+/*****************************/
+/* Server-related functions */
+
+/* Configure the server */
+function ovpn_config_server() {
+ global $config, $g;
+
+ if (isset($config['ovpn']['server']['enable'])) {
+
+ if ($g['booting'])
+ echo "Starting OpenVPN server... ";
+
+ /* kill any running openvpn daemon */
+ killbypid($g['varrun_path']."/ovpn_srv.pid");
+
+ /* Remove old certs & keys */
+ unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_dh.pem");
+
+ /* Copy the TLS-Server certs & keys to disk */
+ $fd = @fopen("{$g['vardb_path']}/ovpn_ca_cert.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($config['ovpn']['server']['ca_cert'])."\n");
+ fclose($fd);
+ }
+ $fd = @fopen("{$g['vardb_path']}/ovpn_srv_cert.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($config['ovpn']['server']['srv_cert'])."\n");
+ fclose($fd);
+ }
+ $fd = @fopen("{$g['vardb_path']}/ovpn_srv_key.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($config['ovpn']['server']['srv_key'])."\n");
+ fclose($fd);
+ }
+ $fd = @fopen("{$g['vardb_path']}/ovpn_dh.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($config['ovpn']['server']['dh_param'])."\n");
+ fclose($fd);
+ }
+
+ /* Start the openvpn daemon */
+ mwexec("/usr/local/sbin/openvpn " . ovpn_srv_config_generate());
+
+ if ($g['booting'])
+ /* Send the boot message */
+ echo "done\n";
+ }
+ else {
+ if (!$g['booting']){
+ /* stop any processes, unload the tap module */
+ /* Remove old certs & keys */
+ unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_srv_cert.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_srv_key.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_dh.pem");
+ killbypid("{$g['varrun_path']}/ovpn_srv.pid");
+ if ($config['ovpn']['server']['tun_iface'] == 'tap0')
+ ovpn_unlink_tap();
+ }
+ }
+ return 0;
+}
+
+/* Generate the config for a OpenVPN server */
+function ovpn_srv_config_generate() {
+ global $config, $g;
+ $server = $config['ovpn']['server'];
+
+ /* First the generic stuff:
+ - We are a server
+ - We are a TLS Server (for authentication)
+ - We will run without privilege
+ */
+ $ovpn_config = "--daemon --user nobody --group nobody --verb {$server['verb']} ";
+
+ /* pid file */
+ $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_srv.pid ";
+
+ /* interface */
+ $ovpn_config .= "--dev {$server['tun_iface']} ";
+
+ /* port */
+ $ovpn_config .= "--port {$server['port']} ";
+
+ /* Interface binding - 1 or all */
+ if ($server['bind_iface'] != 'all') {
+ if ($ipaddr = ovpn_get_ip($server['bind_iface']))
+ $ovpn_config .= "--local $ipaddr ";
+ else
+ return "Interface bridged";
+
+ }
+
+ /* Client to client routing (off by default) */
+ if (isset($server['cli2cli']))
+ $ovpn_config .= "--client-to-client ";
+
+ /* Set maximum simultaneous clients */
+ $ovpn_config .= "--max-clients {$server['maxcli']} ";
+
+ /* New --server macro simplifies config */
+ $mask = ovpn_calc_mask($server['prefix']);
+ $ovpn_config .= "--server {$server['ipblock']} {$mask} ";
+
+ /* TLS-Server params */
+ $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert.pem ";
+ $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_srv_cert.pem ";
+ $ovpn_config .= "--key {$g['vardb_path']}/ovpn_srv_key.pem ";
+ $ovpn_config .= "--dh {$g['vardb_path']}/ovpn_dh.pem ";
+
+ /* Data channel encryption cipher*/
+ $ovpn_config .= "--cipher {$server['crypto']} ";
+
+ /* Duplicate CNs */
+ if (isset($server['dupcn']))
+ $ovpn_config .= "--duplicate-cn ";
+
+ /* Client push - redirect gateway */
+ if (isset($server['psh_options']['redir'])){
+ if (isset($server['psh_options']['redir_loc']))
+ $ovpn_config .= "--push \"redirect-gateway 'local'\" ";
+ else
+ $ovpn_config .= "--push \"redirect-gateway\" ";
+ }
+
+ /* Client push - route delay */
+ if (isset($server['psh_options']['rte_delay']))
+ $ovpn_config .= "--push \"route-delay {$server['psh_options']['rte_delay']}\" ";
+
+ /* Client push - ping (note we set both server and client) */
+ if (isset ($server['psh_options']['ping'])){
+ $ovpn_config .= "--ping {$server['psh_options']['ping']} ";
+ $ovpn_config .= "--push \"ping {$server['psh_options']['ping']}\" ";
+ }
+
+ /* Client push - ping-restart (note server uses 2 x client interval) */
+ if (isset ($server['psh_options']['pingrst'])){
+ $interval = $server['psh_options']['pingrst'];
+ $ovpn_config .= "--ping-restart " . ($interval * 2) . " ";
+ $ovpn_config .= "--push \"ping-restart $interval\" ";
+ }
+
+ /* Client push - ping-exit (set on client) */
+ if (isset ($server['psh_options']['pingexit'])){
+ $ovpn_config .= "--ping-exit {$server['psh_options']['pingexit']} ";
+ $ovpn_config .= "--push \"ping-exit {$server['psh_options']['pingexit']}\" ";
+ }
+
+ /* Client push - inactive (set on client) */
+ if (isset ($server['psh_options']['inact'])){
+ $ovpn_config .= "--inactive {$server['psh_options']['pingexit']} ";
+ $ovpn_config .= "--push \"inactive {$server['psh_options']['inact']}\" ";
+ }
+
+ //trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
+ return $ovpn_config;
+}
+
+/* Define an OVPN Server tunnel interface in the interfaces array and assign a name */
+function ovpn_server_iface(){
+ global $config, $g;
+
+ $i = 1;
+ while (true) {
+ $ifname = 'opt' . $i;
+ if (is_array($config['interfaces'][$ifname])) {
+ if ((isset($config['interfaces'][$ifname]['ovpn']))
+ && ($config['interfaces'][$ifname]['ovpn'] == 'server'))
+ /* Already an interface defined - overwrite */
+ break;
+ }
+ else {
+ /* No existing entry, this is first unused */
+ $config['interfaces'][$ifname] = array();
+ break;
+ }
+ $i++;
+ }
+ $config['interfaces'][$ifname]['descr'] = "OVPN server";
+ $config['interfaces'][$ifname]['if'] = $config['ovpn']['server']['tun_iface'];
+ $config['interfaces'][$ifname]['ipaddr'] = long2ip( ip2long($config['ovpn']['server']['ipblock']) + 1);
+ $config['interfaces'][$ifname]['subnet'] = $config['ovpn']['server']['prefix'];
+ $config['interfaces'][$ifname]['enable'] = isset($config['ovpn']['server']['enable']) ? true : false;
+ $config['interfaces'][$ifname]['ovpn'] = 'server';
+
+ write_config();
+
+ return "OpenVPN server interface defined";
+}
+
+/********************************************************/
+/* Client related functions */
+function ovpn_config_client() {
+ /* Boot time configuration */
+ global $config, $g;
+
+ foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
+ if (isset($client['enable'])) {
+
+ if ($g['booting'])
+ echo "Starting OpenVPN client $id... ";
+
+ /* kill any running openvpn daemon */
+ killbypid("{$g['varrun_path']}/ovpn_client{$id}.pid");
+
+ /* Remove old certs & keys */
+ unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$id}.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$id}.pem");
+
+ /* Copy the TLS-Client certs & keys to disk */
+ /*$fd = @fopen("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem", "w");*/
+ $fd = fopen("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['ca_cert'])."\n");
+ fclose($fd);
+ }
+ else
+ trigger_error("OVPN: No open for CA", E_USER_NOTICE);
+ $fd = fopen($g['vardb_path']."/ovpn_cli_cert_".$id.".pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['cli_cert'])."\n");
+ fclose($fd);
+ }
+ $fd = fopen($g['vardb_path']."/ovpn_cli_key_".$id.".pem", "w");
+ if ($fd) {
+ fwrite($fd, base64_decode($client['cli_key'])."\n");
+ fclose($fd);
+ }
+
+ /* Start openvpn for this client */
+ mwexec("/usr/local/sbin/openvpn " . ovpn_cli_config_generate($id));
+
+ if ($g['booting'])
+ /* Send the boot message */
+ echo "done\n";
+ }
+ else {
+ if (!$g['booting']){
+ /* stop any processes, unload the tap module */
+ /* Remove old certs & keys */
+ unlink_if_exists("{$g['vardb_path']}/ovpn_ca_cert_{$id}.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_cli_cert_{$id}.pem");
+ unlink_if_exists("{$g['vardb_path']}/ovpn_cli_key_{$id}.pem");
+ killbypid("{$g['varrun_path']}/ovpn_client{$id}.pid");
+ if ($client['type'] == "tap")
+ ovpn_unlink_tap();
+ }
+ }
+ }
+ return 0;
+
+}
+
+/* Kill off a running client process */
+function ovpn_client_kill($id) {
+ global $g;
+
+ killbypid("{$g['varrun_path']}/ovpn_client{$id}.pid");
+ return 0;
+}
+
+function ovpn_cli_config_generate($id) {
+ /* configure the named client */
+ global $config, $g;
+ $client = $config['ovpn']['client']['tunnel'];
+
+ /* Client support in 2.0 is very simple */
+
+ $ovpn_config = "--client --daemon --verb 1 ";
+
+ /* pid file */
+ $ovpn_config .= "--writepid {$g['varrun_path']}/ovpn_client{$id}.pid ";
+
+ /* interface */
+ $ovpn_config .= "--dev {$client[$id]['if']} ";
+
+ /* protocol */
+ $ovpn_config .= "--proto {$client[$id]['proto']} ";
+
+ /* port */
+ $ovpn_config .= "--lport {$client[$id]['cport']} ";
+
+ /* server location */
+ $ovpn_config .= "--remote {$client[$id]['saddr']} {$client[$id]['sport']} ";
+
+ /* TLS-Server params */
+ $ovpn_config .= "--ca {$g['vardb_path']}/ovpn_ca_cert_{$id}.pem ";
+ $ovpn_config .= "--cert {$g['vardb_path']}/ovpn_cli_cert_{$id}.pem ";
+ $ovpn_config .= "--key {$g['vardb_path']}/ovpn_cli_key_{$id}.pem ";
+
+ /* Data channel encryption cipher*/
+ $ovpn_config .= "--cipher {$client[$id]['crypto']} ";
+
+ //trigger_error("OVPN: $ovpn_config", E_USER_NOTICE);
+ return $ovpn_config;
+}
+
+/* Define an OVPN tunnel interface in the interfaces array for each client */
+function ovpn_client_iface(){
+ global $config;
+
+ foreach ($config['ovpn']['client']['tunnel'] as $id => $client) {
+ if (isset($client['enable'])) {
+ $i = 1;
+ while (true) {
+ $ifname = 'opt' . $i;
+ if (is_array($config['interfaces'][$ifname])) {
+ if ((isset($config['interfaces'][$ifname]['ovpn']))
+ && ($config['interfaces'][$ifname]['ovpn'] == "client{$id}"))
+ /* Already an interface defined - overwrite */
+ break;
+ }
+ else {
+ /* No existing entry, this is first unused */
+ $config['interfaces'][$ifname] = array();
+ break;
+ }
+ $i++;
+ }
+ if (isset($client['descr']))
+ $config['interfaces'][$ifname]['descr'] = $client['descr'];
+ else
+ $config['interfaces'][$ifname]['descr'] = "OVPN client-{$id}";
+ $config['interfaces'][$ifname]['if'] = $client['if'];
+ $config['interfaces'][$ifname]['ipaddr'] = "0.0.0.0";
+ $config['interfaces'][$ifname]['subnet'] = "0";
+ $config['interfaces'][$ifname]['enable'] = isset($client['enable']) ? true : false;
+ $config['interfaces'][$ifname]['ovpn'] = "client{$id}";
+ write_config();
+ }
+ }
+ return "OpenVPN client interfaces defined";
+}
+
+/* Delete a client interface definition */
+function ovpn_client_iface_del($id) {
+ global $config;
+
+ $i = 1;
+ while (true) {
+ $ifname = 'opt' . $i;
+ if (is_array($config['interfaces'][$ifname])) {
+ if ((isset($config['interfaces'][$ifname]['ovpn']))
+ && ($config['interfaces'][$ifname]['ovpn'] == "client{$id}"))
+ unset($config['interfaces'][$ifname]);
+ }
+ }
+}
+
+/******************/
+/* Misc functions */
+
+/* Calculate the last address in a range given the start and /prefix */
+function ovpn_calc_end($start, $prefix){
+
+ $first = ip2long($start);
+ $last = pow(2,(32 - $prefix)) - 1 + $first;
+ return long2ip($last);
+}
+
+/* Calculate a mask given a /prefix */
+function ovpn_calc_mask($prefix){
+
+ return long2ip(ip2long("255.255.255.255") - (pow( 2, (32 - $prefix)) - 1));
+}
+
+/* Read in a file from the $_FILES array */
+function ovpn_get_file($file){
+ global $g;
+
+ if (!is_uploaded_file($_FILES[$file]['tmp_name'])){
+ trigger_error("Bad file upload".$_FILES[$file]['error'], E_USER_NOTICE);
+ return NULL;
+ }
+ $contents = file_get_contents($_FILES[$file]['tmp_name']);
+ return $contents;
+}
+
+
+/* Get the IP address of a specified interface */
+function ovpn_get_ip($iface){
+ global $config;
+
+ if ($iface == 'wan')
+ return get_current_wan_address();
+
+ if ($config['interfaces'][$iface]['bridge'])
+ /* No bridging (yet) */
+ return false;
+ return $config['interfaces'][$iface]['ipaddr'];
+}
+
+/* Get a list of the cipher options supported by OpenVPN */
+function ovpn_get_cipher_list(){
+
+/* exec("/usr/local/sbin/openvpn --show-ciphers", $raw);
+ print_r ($raw);
+
+ $ciphers = preg_grep('/ bit default key /', $raw);
+
+ for($i = 0; $i <count($ciphers); $i++){
+ $tmp = explode(' ',$ciphers[$i]);
+ $cipher_list["$tmp[0]"] = "{$tmp[0]} ({$tmp[1]} {$tmp[2]})";
+ }
+*/
+ $cipher_list = array('DES-CBC' => 'DES-CBC (64 bit)',
+ 'RC2-CBC' => 'RC2-CBC (128 bit)',
+ 'DES-EDE-CBC' => 'DES-EDE-CBC (128 bit)',
+ 'DES-EDE3-CBC' => 'DES-EDE3-CBC (192 bit)',
+ 'DESX-CBC' => 'DESX-CBC (192 bit)',
+ 'BF-CBC' => 'BF-CBC (128 bit)',
+ 'RC2-40-CBC' => 'RC2-40-CBC (40 bit)',
+ 'CAST5-CBC' => 'CAST5-CBC (128 bit)',
+ 'RC5-CBC' => 'RC5-CBC (128 bit)',
+ 'RC2-64-CBC' => 'RC2-64-CBC (64 bit)',
+ 'AES-128-CBC' => 'AES-128-CBC (128 bit)',
+ 'AES-192-CBC' => 'AES-192-CBC (192 bit)',
+ 'AES-256-CBC' => 'AES-256-CBC (256 bit)');
+ return $cipher_list;
+}
+
+
+/* Build a list of the current real interfaces */
+function ovpn_real_interface_list(){
+ global $config;
+
+ $interfaces = array('all' => 'ALL',
+ 'lan' => 'LAN',
+ 'wan' => 'WAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if (isset($config['interfaces']['opt' . $i]['ovpn']))
+ /* Hide our own interface */
+ break;
+ if (isset($config['interfaces']['opt' . $i]['enable']))
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ return $interfaces;
+}
+
+
+/* lock openvpn information, decide that the lock file is stale after
+ 10 seconds */
+function ovpn_lock() {
+
+ global $g;
+
+ $lockfile = "{$g['varrun_path']}/ovpn.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 ovpn_unlock() {
+
+ global $g;
+
+ $lockfile = "{$g['varrun_path']}/ovpn.lock";
+
+ if (file_exists($lockfile))
+ unlink($lockfile);
+}
+
+?>
diff --git a/etc/inc/services.inc b/etc/inc/services.inc
new file mode 100644
index 0000000..17bc959
--- /dev/null
+++ b/etc/inc/services.inc
@@ -0,0 +1,440 @@
+<?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;
+ }
+
+ $dhcpdconf = <<<EOD
+option domain-name "{$syscfg['domain']}";
+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']);
+
+ $dnscfg = "";
+
+ if ($dhcpifconf['domain']) {
+ $dnscfg .= " option domain-name \"{$dhcpifconf['domain']}\";\n";
+ }
+
+ if (is_array($dhcpifconf['dnsserver']) && ($dhcpifconf['dnsserver'][0])) {
+ $dnscfg .= " option domain-name-servers " . join(",", $dhcpifconf['dnsserver']) . ";";
+ } else if (isset($config['dnsmasq']['enable'])) {
+ $dnscfg .= " option domain-name-servers " . $ifcfg['ipaddr'] . ";";
+ } else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) {
+ $dnscfg .= " option domain-name-servers " . join(",", $syscfg['dnsserver']) . ";";
+ }
+
+ $dhcpdconf .= "subnet $subnet netmask $subnetmask {\n";
+ $dhcpdconf .= " pool {\n";
+ if (isset($dhcpifconf['denyunknown']))
+ $dhcpdconf .= " deny unknown clients;\n";
+
+ if ($dhcpifconf['gateway'])
+ $routers = $dhcpifconf['gateway'];
+ else
+ $routers = $ifcfg['ipaddr'];
+
+ $dhcpdconf .= <<<EOD
+ range {$dhcpifconf['range']['from']} {$dhcpifconf['range']['to']};
+ }
+ option routers {$routers};
+$dnscfg
+
+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";
+ }
+
+ if ($dhcpifconf['next-server'])
+ $dhcpdconf .= " next-server {$dhcpifconf['next-server']};\n";
+ if ($dhcpifconf['filename'])
+ $dhcpdconf .= " filename \"{$dhcpifconf['filename']}\";\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']};
+
+EOD;
+ if ($sm['ipaddr'])
+ $dhcpdconf .= " fixed-address {$sm['ipaddr']};\n";
+
+ $dhcpdconf .= "}\n";
+ $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_dhcrelay_configure() {
+ global $config, $g;
+
+ /* kill any running dhcrelay */
+ killbypid("{$g['varrun_path']}/dhcrelay.pid");
+
+ $dhcrelaycfg = $config['dhcrelay'];
+
+ /* DHCPRelay enabled on any interfaces? */
+ $dhcrelayenable = false;
+ foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
+ if (isset($dhcrelayifconf['enable']) &&
+ (($dhcrelayif == "lan") ||
+ (isset($config['interfaces'][$dhcrelayif]['enable']) &&
+ $config['interfaces'][$dhcrelayif]['if'] && (!$config['interfaces'][$dhcrelayif]['bridge']))))
+ $dhcrelayenable = true;
+ }
+
+ if (!$dhcrelayenable)
+ return 0;
+
+ if ($g['booting'])
+ echo "Starting DHCP relay service... ";
+ else
+ sleep(1);
+
+ $dhcrelayifs = array();
+ foreach ($dhcrelaycfg as $dhcrelayif => $dhcrelayifconf) {
+
+ $ifcfg = $config['interfaces'][$dhcrelayif];
+
+ if (!isset($dhcrelayifconf['enable']) ||
+ (($dhcrelayif != "lan") &&
+ (!isset($ifcfg['enable']) || !$ifcfg['if'] || $ifcfg['bridge'])))
+ continue;
+
+ $dhcrelayifs[] = $ifcfg['if'];
+ }
+
+ /* In order for the relay to work, it needs to be active on the
+ interface in which the destination server sits */
+ foreach ($config['interfaces'] as $ifname) {
+ $subnet = $ifname['ipaddr'] . "/" . $ifname['subnet'];
+ if (ip_in_subnet($dhcrelaycfg['server'],$subnet))
+ $destif = $ifname['if'];
+ }
+
+ if (!isset($destif))
+ $destif = $config['interfaces']['wan']['if'];
+
+ $dhcrelayifs[] = $destif;
+ $dhcrelayifs = array_unique($dhcrelayifs);
+
+ /* fire up dhcrelay */
+ $cmd = "/usr/local/sbin/dhcrelay -i " . join(" -i ", $dhcrelayifs);
+
+ if (isset($dhcrelaycfg['agentoption']))
+ $cmd .= " -a -m replace";
+
+ $cmd .= " {$dhcrelaycfg['server']}";
+ mwexec($cmd);
+
+ 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") ||
+ ($config['interfaces']['wan']['ipaddr'] == "bigpond"))) {
+
+ $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/etc/inc/shaper.inc b/etc/inc/shaper.inc
new file mode 100644
index 0000000..71e0575
--- /dev/null
+++ b/etc/inc/shaper.inc
@@ -0,0 +1,403 @@
+<?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['pfqueueing']['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 delete set 4");
+ 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 {
+ mwexec("/sbin/sysctl net.link.ether.bridge_ipfw=0");
+ if (!isset($config['captiveportal']['enable'])) {
+ /* unload ipfw and dummynet */
+ #mwexec("/sbin/kldunload dummynet");
+ #mwexec("/sbin/kldunload ipfw");
+ } else {
+ /* captive portal is on - just remove our rules */
+ mwexec("/sbin/ipfw -f delete set 4");
+ mwexec("/sbin/ipfw -f pipe flush");
+ }
+ }
+
+ 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'];
+ }
+
+ $rulei = 50000;
+
+ /* add a rule to pass all traffic from/to the firewall,
+ so the user cannot lock himself out of the webGUI */
+ $shaperrules = "add $rulei set 4 pass all from $lanip to any\n"; $rulei++;
+ $shaperrules .= "add $rulei set 4 pass all from any to $lanip\n"; $rulei++;
+
+ /* generate rules */
+ if (isset($config['pfqueueing']['rule']))
+ foreach ($config['pfqueueing']['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") {
+ $i++;
+ continue;
+ }
+
+ $nif = $g['n_pptp_units'];
+ $ispptp = true;
+ } else {
+
+ if (strstr($rule['interface'], "opt")) {
+ if (!array_key_exists($rule['interface'], $optcfg)) {
+ $i++;
+ continue;
+ }
+ }
+
+ $nif = 1;
+ $ispptp = false;
+ }
+
+ if ($pptpdcfg['mode'] != "server") {
+ if (($rule['source']['network'] == "pptp") ||
+ ($rule['destination']['network'] == "pptp")) {
+ $i++;
+ continue;
+ }
+ }
+
+ if (strstr($rule['source']['network'], "opt")) {
+ if (!array_key_exists($rule['source']['network'], $optcfg)) {
+ $i++;
+ continue;
+ }
+ }
+ if (strstr($rule['destination']['network'], "opt")) {
+ if (!array_key_exists($rule['destination']['network'], $optcfg)) {
+ $i++;
+ continue;
+ }
+ }
+
+ /* check for unresolvable aliases */
+ if ($rule['source']['address'] && !alias_expand($rule['source']['address'])) {
+ $i++;
+ continue;
+ }
+ if ($rule['destination']['address'] && !alias_expand($rule['destination']['address'])) {
+ $i++;
+ continue;
+ }
+
+ for ($iif = 0; $iif < $nif; $iif++) {
+
+ /* pipe or queue? */
+ if (isset($rule['targetpipe']) && isset($config['pfqueueing']['pipe'][$rule['targetpipe']])) {
+ $pipen = $rule['targetpipe'] + 1;
+ $line = "add $rulei set 4 pipe $pipen "; $rulei++;
+ } else if (isset($rule['targetqueue']) && isset($config['pfqueueing']['queue'][$rule['targetqueue']])) {
+ $queuen = $rule['targetqueue'] + 1;
+ $line = "add $rulei set 4 queue $queuen "; $rulei++;
+ } 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 (!isset($rule['protocol']) || 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 (!isset($rule['protocol']) || 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['iptos'])
+ $line .= "iptos {$rule['iptos']} ";
+
+ 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['pfqueueing']['pipe'])) {
+ $pipei = 1;
+ foreach ($config['pfqueueing']['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['pfqueueing']['queue'])) {
+ $queuei = 1;
+ foreach ($config['pfqueueing']['queue'] as $queue) {
+
+ $pipen = $queue['targetpipe'] + 1;
+ if (!isset($queue['targetpipe']) || !isset($config['pfqueueing']['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/etc/inc/system.inc b/etc/inc/system.inc
new file mode 100644
index 0000000..d2c0b33
--- /dev/null
+++ b/etc/inc/system.inc
@@ -0,0 +1,563 @@
+<?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
+local3.* %/var/log/vpn.log
+local7.* %/var/log/dhcpd.log
+*.notice;kern.debug;lpr.info;mail.crit;news.err;local0.none;local3.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['vpn'])) {
+ $syslogconf .= <<<EOD
+local3.* @{$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|**.cgi\" -u root -maxproc 16 $portarg" .
+ " -i {$g['varrun_path']}/mini_httpd.pid");
+ } else {
+ $res = mwexec("/usr/local/sbin/mini_httpd -c \"**.php|**.cgi\" -u root" .
+ " -maxproc 16 $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;
+
+ system_reboot_cleanup();
+
+ mwexec("nohup /etc/rc.reboot > /dev/null 2>&1 &");
+}
+
+function system_reboot_sync() {
+ global $g;
+
+ system_reboot_cleanup();
+
+ mwexec("/etc/rc.reboot > /dev/null 2>&1");
+}
+
+function system_reboot_cleanup() {
+ captiveportal_radius_stop_all();
+}
+
+function system_do_shell_commands($early = 0) {
+ global $config, $g;
+
+ if ($early)
+ $cmdn = "earlyshellcmd";
+ else
+ $cmdn = "shellcmd";
+
+ if (is_array($config['system'][$cmdn])) {
+
+ foreach ($config['system'][$cmdn] as $cmd) {
+ exec($cmd);
+ }
+ }
+}
+
+function system_do_extensions() {
+ global $config, $g;
+
+ if (!is_dir("{$g['etc_path']}/inc/ext"))
+ return;
+
+ $dh = @opendir("{$g['etc_path']}/inc/ext");
+ if ($dh) {
+ while (($extd = readdir($dh)) !== false) {
+ if (($extd === ".") || ($extd === ".."))
+ continue;
+ $rcfile = "{$g['etc_path']}/inc/ext/" . $extd . "/rc";
+ if (file_exists($rcfile))
+ passthru($rcfile);
+ }
+ closedir($dh);
+ }
+}
+
+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");
+ }
+}
+
+function system_dmesg_save() {
+ global $g;
+
+ exec("/sbin/dmesg", $dmesg);
+
+ /* find last copyright line (output from previous boots may be present) */
+ $lastcpline = 0;
+
+ for ($i = 0; $i < count($dmesg); $i++) {
+ if (strstr($dmesg[$i], "Copyright (c) 1992-"))
+ $lastcpline = $i;
+ }
+
+ $fd = fopen("{$g['varlog_path']}/dmesg.boot", "w");
+ if (!$fd) {
+ printf("Error: cannot open dmesg.boot in system_dmesg_save().\n");
+ return 1;
+ }
+
+ for ($i = $lastcpline; $i < count($dmesg); $i++)
+ fwrite($fd, $dmesg[$i] . "\n");
+
+ fclose($fd);
+
+ return 0;
+}
+
+function system_set_harddisk_standby() {
+ global $g, $config;
+
+ if ($g['platform'] != "generic-pc")
+ return;
+
+ if (isset($config['system']['harddiskstandby'])) {
+ if ($g['booting']) {
+ echo 'Setting harddisk standby time... ';
+ }
+
+ $standby = $config['system']['harddiskstandby'];
+ // Check for a numeric value
+ if (is_numeric($standby)) {
+ // Sync the disk(s)
+ mwexec('/bin/sync');
+ if (!mwexec('/sbin/sysctl hw.ata.standby=' . ((int)$standby))) {
+ // Reinitialize ATA-drives
+ mwexec('/usr/local/sbin/atareinit');
+ if ($g['booting']) {
+ echo "done\n";
+ }
+ } else if ($g['booting']) {
+ echo "failed\n";
+ }
+ } else if ($g['booting']) {
+ echo "failed\n";
+ }
+ }
+}
+
+?>
diff --git a/etc/inc/util.inc b/etc/inc/util.inc
new file mode 100644
index 0000000..2b3fa67
--- /dev/null
+++ b/etc/inc/util.inc
@@ -0,0 +1,421 @@
+<?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 (broadcast) 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));
+}
+
+function is_numericint($arg) {
+ return (preg_match("/[^0-9]/", $arg) ? false : true);
+}
+
+/* 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
+ (skips VLAN and other virtual interfaces) */
+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|vlan)/", $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;
+}
+
+/* return true if $addr is in $subnet, false if not */
+function ip_in_subnet($addr,$subnet) {
+ list($ip, $mask) = explode('/', $subnet);
+ $mask = 0xffffffff << (32 - $mask);
+ return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask));
+}
+
+/* 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));
+}
+
+/* obtain MAC address given an IP address by looking at the ARP table */
+function arp_get_mac_by_ip($ip) {
+ exec("/usr/sbin/arp -n {$ip}", $arpoutput);
+
+ if ($arpoutput[0]) {
+ $arpi = explode(" ", $arpoutput[0]);
+ $macaddr = $arpi[3];
+ if (is_macaddr($macaddr))
+ return $macaddr;
+ else
+ return false;
+ }
+
+ return false;
+}
+
+?>
diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc
new file mode 100644
index 0000000..b73af46
--- /dev/null
+++ b/etc/inc/vpn.inc
@@ -0,0 +1,559 @@
+<?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();
+
+ $syscfg = $config['system'];
+ $ipseccfg = $config['ipsec'];
+ $lancfg = $config['interfaces']['lan'];
+ $lanip = $lancfg['ipaddr'];
+ $lansa = gen_subnet($lancfg['ipaddr'], $lancfg['subnet']);
+ $lansn = $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");
+
+ /* prefer old SAs only for 30 seconds, then use the new one */
+ mwexec("/sbin/sysctl -w net.key.preferred_oldsa=-30");
+
+ 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 = "";
+
+ $spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n";
+ $spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n";
+
+ 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'];
+ } else if (isset($tunnel['p1']['myident']['ufqdn'])) {
+ $myidentt = "user_fqdn";
+ $myident = $tunnel['p1']['myident']['ufqdn'];
+ }
+
+ $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'];
+ } else if (isset($tunnel['p1']['myident']['ufqdn'])) {
+ $myidentt = "user_fqdn";
+ $myident = $tunnel['p1']['myident']['ufqdn'];
+ }
+
+ $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");
+
+ foreach ($ipseccfg['tunnel'] as $tunnel) {
+ if (isset($tunnel['auto'])) {
+ $remotehost = substr($tunnel['remote-subnet'],0,strpos($tunnel['remote-subnet'],"/"));
+ $srchost = vpn_endpoint_determine($tunnel, $curwanip);
+ if ($srchost)
+ mwexec_bg("/sbin/ping -c 1 -S {$srchost} {$remotehost}");
+ }
+ }
+ }
+ }
+
+ 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 pt{$i}\n";
+ }
+
+ for ($i = 0; $i < $g['n_pptp_units']; $i++) {
+
+ $clientip = long2ip(ip2long($pptpdcfg['remoteip']) + $i);
+ $ngif = "ng" . ($i+1);
+
+ $mpdconf .= <<<EOD
+
+pt{$i}:
+ new -i {$ngif} pt{$i} pt{$i}
+ set ipcp ranges {$pptpdcfg['localip']}/32 {$clientip}/32
+ load pts
+
+EOD;
+ }
+
+ $mpdconf .= <<<EOD
+
+pts:
+ set iface disable on-demand
+ set iface enable proxy-arp
+ set iface enable tcpmssfix
+ set iface idle 1800
+ set iface up-script /usr/local/sbin/vpn-linkup
+ set iface down-script /usr/local/sbin/vpn-linkdown
+ 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 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;
+
+ if (isset($pptpdcfg['radius']['accounting'])) {
+ $mpdconf .= <<<EOD
+ set bundle enable radius-acct
+
+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
+
+pt{$i}:
+ set link type pptp
+ set pptp enable incoming
+ set pptp disable originate
+ set pptp disable windowing
+ 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']}\" {$user['ip']}\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 (is_null($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/etc/inc/xmlparse.inc b/etc/inc/xmlparse.inc
new file mode 100644
index 0000000..1fdadac
--- /dev/null
+++ b/etc/inc/xmlparse.inc
@@ -0,0 +1,205 @@
+<?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 subqueue dnsserver winsserver " .
+ "encryption-algorithm-option hash-algorithm-option hosts tunnel onetoone " .
+ "staticmap route alias pipe queue shellcmd earlyshellcmd mobilekey " .
+ "servernat proxyarpnet passthrumac allowedip wolentry vlan");
+
+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/etc/login.conf b/etc/login.conf
new file mode 100644
index 0000000..fc6b37c
--- /dev/null
+++ b/etc/login.conf
@@ -0,0 +1,316 @@
+# login.conf - login class capabilities database.
+#
+# Remember to rebuild the database after each change to this file:
+#
+# cap_mkdb /etc/login.conf
+#
+# This file controls resource limits, accounting limits and
+# default user environment settings.
+#
+# $FreeBSD: src/etc/login.conf,v 1.34.2.6 2002/07/02 20:06:18 dillon Exp $
+#
+
+# Default settings effectively disable resource limits, see the
+# examples below for a starting point to enable them.
+
+# defaults
+# These settings are used by login(1) by default for classless users
+# Note that entries like "cputime" set both "cputime-cur" and "cputime-max"
+
+default:\
+ :passwd_format=md5:\
+ :copyright=/etc/COPYRIGHT:\
+ :welcome=/etc/motd:\
+ :setenv=MAIL=/var/mail/$,BLOCKSIZE=K,FTP_PASSIVE_MODE=YES:\
+ :path=/sbin /bin /usr/sbin /usr/bin /usr/games /usr/local/sbin /usr/local/bin /usr/X11R6/bin ~/bin:\
+ :nologin=/var/run/nologin:\
+ :cputime=unlimited:\
+ :datasize=unlimited:\
+ :stacksize=unlimited:\
+ :memorylocked=unlimited:\
+ :memoryuse=unlimited:\
+ :filesize=unlimited:\
+ :coredumpsize=unlimited:\
+ :openfiles=unlimited:\
+ :maxproc=unlimited:\
+ :sbsize=unlimited:\
+ :vmemoryuse=unlimited:\
+ :priority=0:\
+ :ignoretime@:\
+ :umask=022:
+
+
+#
+# A collection of common class names - forward them all to 'default'
+# (login would normally do this anyway, but having a class name
+# here suppresses the diagnostic)
+#
+standard:\
+ :tc=default:
+xuser:\
+ :tc=default:
+staff:\
+ :tc=default:
+daemon:\
+ :tc=default:
+news:\
+ :tc=default:
+dialer:\
+ :tc=default:
+
+#
+# Root can always login
+#
+# N.B. login_getpwclass(3) will use this entry for the root account,
+# in preference to 'default'.
+root:\
+ :ignorenologin:\
+ :tc=default:
+
+#
+# Russian Users Accounts. Setup proper environment variables.
+#
+russian|Russian Users Accounts:\
+ :charset=KOI8-R:\
+ :lang=ru_RU.KOI8-R:\
+ :tc=default:
+
+
+######################################################################
+######################################################################
+##
+## Example entries
+##
+######################################################################
+######################################################################
+
+## Example defaults
+## These settings are used by login(1) by default for classless users
+## Note that entries like "cputime" set both "cputime-cur" and "cputime-max"
+#
+#default:\
+# :cputime=infinity:\
+# :datasize-cur=22M:\
+# :stacksize-cur=8M:\
+# :memorylocked-cur=10M:\
+# :memoryuse-cur=30M:\
+# :filesize=infinity:\
+# :coredumpsize=infinity:\
+# :maxproc-cur=64:\
+# :openfiles-cur=64:\
+# :priority=0:\
+# :requirehome@:\
+# :umask=022:\
+# :tc=auth-defaults:
+#
+#
+##
+## standard - standard user defaults
+##
+#standard:\
+# :copyright=/etc/COPYRIGHT:\
+# :welcome=/etc/motd:\
+# :setenv=MAIL=/var/mail/$,BLOCKSIZE=K:\
+# :path=~/bin /bin /usr/bin /usr/local/bin:\
+# :manpath=/usr/share/man /usr/local/man:\
+# :nologin=/var/run/nologin:\
+# :cputime=1h30m:\
+# :datasize=8M:\
+# :vmemoryuse=100M:\
+# :stacksize=2M:\
+# :memorylocked=4M:\
+# :memoryuse=8M:\
+# :filesize=8M:\
+# :coredumpsize=8M:\
+# :openfiles=24:\
+# :maxproc=32:\
+# :priority=0:\
+# :requirehome:\
+# :passwordtime=90d:\
+# :umask=002:\
+# :ignoretime@:\
+# :tc=default:
+#
+#
+##
+## users of X (needs more resources!)
+##
+#xuser:\
+# :manpath=/usr/share/man /usr/X11R6/man /usr/local/man:\
+# :cputime=4h:\
+# :datasize=12M:\
+# :vmemoryuse=infinity:\
+# :stacksize=4M:\
+# :filesize=8M:\
+# :memoryuse=16M:\
+# :openfiles=32:\
+# :maxproc=48:\
+# :tc=standard:
+#
+#
+##
+## Staff users - few restrictions and allow login anytime
+##
+#staff:\
+# :ignorenologin:\
+# :ignoretime:\
+# :requirehome@:\
+# :accounted@:\
+# :path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
+# :umask=022:\
+# :tc=standard:
+#
+#
+##
+## root - fallback for root logins
+##
+#root:\
+# :path=~/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
+# :cputime=infinity:\
+# :datasize=infinity:\
+# :stacksize=infinity:\
+# :memorylocked=infinity:\
+# :memoryuse=infinity:\
+# :filesize=infinity:\
+# :coredumpsize=infinity:\
+# :openfiles=infinity:\
+# :maxproc=infinity:\
+# :memoryuse-cur=32M:\
+# :maxproc-cur=64:\
+# :openfiles-cur=1024:\
+# :priority=0:\
+# :requirehome@:\
+# :umask=022:\
+# :tc=auth-root-defaults:
+#
+#
+##
+## Settings used by /etc/rc
+##
+#daemon:\
+# :coredumpsize@:\
+# :coredumpsize-cur=0:\
+# :datasize=infinity:\
+# :datasize-cur@:\
+# :maxproc=512:\
+# :maxproc-cur@:\
+# :memoryuse-cur=64M:\
+# :memorylocked-cur=64M:\
+# :openfiles=1024:\
+# :openfiles-cur@:\
+# :stacksize=16M:\
+# :stacksize-cur@:\
+# :tc=default:
+#
+#
+##
+## Settings used by news subsystem
+##
+#news:\
+# :path=/usr/local/news/bin /bin /sbin /usr/bin /usr/sbin /usr/local/bin /usr/local/sbin:\
+# :cputime=infinity:\
+# :filesize=128M:\
+# :datasize-cur=64M:\
+# :stacksize-cur=32M:\
+# :coredumpsize-cur=0:\
+# :maxmemorysize-cur=128M:\
+# :memorylocked=32M:\
+# :maxproc=128:\
+# :openfiles=256:\
+# :tc=default:
+#
+#
+##
+## The dialer class should be used for a dialup PPP/SLIP accounts
+## Welcome messages/news suppressed
+##
+#dialer:\
+# :hushlogin:\
+# :requirehome@:\
+# :cputime=unlimited:\
+# :filesize=2M:\
+# :datasize=2M:\
+# :stacksize=4M:\
+# :coredumpsize=0:\
+# :memoryuse=4M:\
+# :memorylocked=1M:\
+# :maxproc=16:\
+# :openfiles=32:\
+# :tc=standard:
+#
+#
+##
+## Site full-time 24/7 PPP/SLIP connections
+## - no time accounting, restricted to access via dialin lines
+##
+#site:\
+# :ignoretime:\
+# :passwordtime@:\
+# :refreshtime@:\
+# :refreshperiod@:\
+# :sessionlimit@:\
+# :autodelete@:\
+# :expireperiod@:\
+# :graceexpire@:\
+# :gracetime@:\
+# :warnexpire@:\
+# :warnpassword@:\
+# :idletime@:\
+# :sessiontime@:\
+# :daytime@:\
+# :weektime@:\
+# :monthtime@:\
+# :warntime@:\
+# :accounted@:\
+# :tc=dialer:\
+# :tc=staff:
+#
+#
+##
+## Example standard accounting entries for subscriber levels
+##
+#
+#subscriber|Subscribers:\
+# :accounted:\
+# :refreshtime=180d:\
+# :refreshperiod@:\
+# :sessionlimit@:\
+# :autodelete=30d:\
+# :expireperiod=180d:\
+# :graceexpire=7d:\
+# :gracetime=10m:\
+# :warnexpire=7d:\
+# :warnpassword=7d:\
+# :idletime=30m:\
+# :sessiontime=4h:\
+# :daytime=6h:\
+# :weektime=40h:\
+# :monthtime=120h:\
+# :warntime=4h:\
+# :tc=standard:
+#
+#
+##
+## Subscriber accounts. These accounts have their login times
+## accounted and have access limits applied.
+##
+#subppp|PPP Subscriber Accounts:\
+# :tc=dialer:\
+# :tc=subscriber:
+#
+#
+#subslip|SLIP Subscriber Accounts:\
+# :tc=dialer:\
+# :tc=subscriber:
+#
+#
+#subshell|Shell Subscriber Accounts:\
+# :tc=subscriber:
+#
+##
+## If you want some of the accounts to use traditional UNIX DES based
+## password hashes.
+##
+#des_users:\
+# :passwd_format=des:\
+# :tc=default:
diff --git a/etc/master.passwd b/etc/master.passwd
new file mode 100644
index 0000000..88b0dd1
--- /dev/null
+++ b/etc/master.passwd
@@ -0,0 +1,26 @@
+# $FreeBSD: src/etc/master.passwd,v 1.39 2004/08/01 21:33:47 markm Exp $
+#
+root::0:0::0:0:Charlie &:/root:/etc/rc.initial
+toor:*:0:0::0:0:Bourne-again Superuser:/root:
+daemon:*:1:1::0:0:Owner of many system processes:/root:/usr/sbin/nologin
+operator:*:2:5::0:0:System &:/:/usr/sbin/nologin
+bin:*:3:7::0:0:Binaries Commands and Source:/:/usr/sbin/nologin
+tty:*:4:65533::0:0:Tty Sandbox:/:/usr/sbin/nologin
+kmem:*:5:65533::0:0:KMem Sandbox:/:/usr/sbin/nologin
+games:*:7:13::0:0:Games pseudo-user:/usr/games:/usr/sbin/nologin
+news:*:8:8::0:0:News Subsystem:/:/usr/sbin/nologin
+man:*:9:9::0:0:Mister Man Pages:/usr/share/man:/usr/sbin/nologin
+sshd:*:22:22::0:0:Secure Shell Daemon:/var/empty:/usr/sbin/nologin
+smmsp:*:25:25::0:0:Sendmail Submission User:/var/spool/clientmqueue:/usr/sbin/nologin
+mailnull:*:26:26::0:0:Sendmail Default User:/var/spool/mqueue:/usr/sbin/nologin
+bind:*:53:53::0:0:Bind Sandbox:/:/usr/sbin/nologin
+proxy:*:62:62::0:0:Packet Filter pseudo-user:/nonexistent:/usr/sbin/nologin
+_pflogd:*:64:64::0:0:pflogd privsep user:/var/empty:/usr/sbin/nologin
+uucp:*:66:66::0:0:UUCP pseudo-user:/var/spool/uucppublic:/usr/local/libexec/uucp/uucico
+pop:*:68:6::0:0:Post Office Owner:/nonexistent:/usr/sbin/nologin
+www:*:80:80::0:0:World Wide Web Owner:/nonexistent:/usr/sbin/nologin
+nobody:*:65534:65534::0:0:Unprivileged user:/nonexistent:/usr/sbin/nologin
+distcc:*:1001:1001::0:0:Distcc:/home/distcc:/sbin/nologin
+dhcpd:*:1002:1002::0:0:DHCP Daemon:/nonexistent:/sbin/nologin
+admin:*:101:101::0:0:Admin User:/home/admin:/etc/rc.initial
+
diff --git a/etc/networks b/etc/networks
new file mode 100644
index 0000000..92982b5
--- /dev/null
+++ b/etc/networks
@@ -0,0 +1,17 @@
+# $FreeBSD: src/etc/networks,v 1.3 1999/08/27 23:23:42 peter Exp $
+# @(#)networks 5.1 (Berkeley) 6/30/90
+#
+# Your Local Networks Database
+#
+your-net 127 # your comment
+your-netmask 255.255.255 # subnet mask for your-net
+
+#
+# Your subnets
+#
+subnet1 127.0.1 alias1 # comment 1
+subnet2 127.0.2 alias2 # comment 2
+
+#
+# Internet networks (from nic.ddn.mil)
+#
diff --git a/etc/pamd.conf b/etc/pamd.conf
new file mode 100644
index 0000000..78df63d
--- /dev/null
+++ b/etc/pamd.conf
@@ -0,0 +1,55 @@
+# Configuration file for Pluggable Authentication Modules (PAM).
+#
+# This file controls the authentication methods that login and other
+# utilities use. See pam(8) for a description of its format.
+#
+# $FreeBSD: src/etc/pam.conf,v 1.6.2.18 2003/02/15 17:20:27 des Exp $
+#
+# service-name module-type control-flag module-path arguments
+#
+# module-type:
+# auth: prompt for a password to authenticate that the user is
+# who they say they are, and set any credentials.
+# account: non-authentication based authorization, based on time,
+# resources, etc.
+# session: housekeeping before and/or after login.
+# password: update authentication tokens.
+#
+# control-flag: How libpam handles success or failure of the module.
+# required: success is required, and on failure all remaining
+# modules are run.
+# requisite: success is required, and on failure no remaining
+# modules are run.
+# sufficient: success is sufficient, and if no previous required
+# module failed, no remaining modules are run.
+# optional: ignored unless the other modules return PAM_IGNORE.
+#
+# arguments:
+# Passed to the module; module-specific plus some generic ones:
+# debug: syslog debug info.
+# no_warn: return no warning messages to the application.
+# use_first_pass: try authentication using password from the
+# preceding auth module.
+# try_first_pass: first try authentication using password from
+# the preceding auth module, and if that fails
+# prompt for a new password.
+# use_mapped_pass: convert cleartext password to a crypto key.
+# expose_account: allow printing more info about the user when
+# prompting.
+#
+# Each final entry must say "required" -- otherwise, things don't
+# work quite right. If you delete a final entry, be sure to change
+# "sufficient" to "required" in the entry before it.
+#
+## OpenSSH with PAM support requires similar modules. The session one is
+## a bit strange, though...
+sshd auth sufficient pam_skey.so
+sshd auth sufficient pam_opie.so no_fake_prompts
+#sshd auth requisite pam_opieaccess.so
+#sshd auth sufficient pam_kerberosIV.so try_first_pass
+#sshd auth sufficient pam_krb5.so try_first_pass
+sshd auth required pam_unix.so try_first_pass
+sshd account required pam_unix.so
+sshd password required pam_permit.so
+sshd session required pam_permit.so
+
diff --git a/etc/passwd b/etc/passwd
new file mode 100644
index 0000000..86c9b58
--- /dev/null
+++ b/etc/passwd
@@ -0,0 +1,10 @@
+root:*:0:0:Charlie &:/root:/etc/rc.initial
+toor:*:0:0:Bourne-again Superuser:/root:
+daemon:*:1:1:Owner of many system processes:/root:/sbin/nologin
+operator:*:2:5:System &:/:/sbin/nologin
+bin:*:3:7:Binaries Commands and Source:/:/sbin/nologin
+tty:*:4:65533:Tty Sandbox:/:/sbin/nologin
+kmem:*:5:65533:KMem Sandbox:/:/sbin/nologin
+www:*:80:80:World Wide Web Owner:/nonexistent:/sbin/nologin
+nobody:*:65534:65534:Unprivileged user:/nonexistent:/sbin/nologin
+admin:*:101:101:Admin Account:/home/admin:/bin/sh
diff --git a/etc/pccard.conf b/etc/pccard.conf
new file mode 100644
index 0000000..75fa24a
--- /dev/null
+++ b/etc/pccard.conf
@@ -0,0 +1,435 @@
+
+# Generally available IO ports
+io 0x240-0x360
+# on i386 IRQs can be any of 3 4 5 7 9 10 11 12 14 15
+# on pc98 IRQs can be any of 3 5 6 9 10 11 12 13
+# but *MUST* *NOT* be used by anything else, unless you are using current
+# and a PCI cardbus bridge that allows sharing. Even then, the rules
+# for interrupt sharing can be tricky.
+# Generally available IRQs (Built-in sound-card owners remove 5)
+irq 3 5 10 11 15
+# Available memory slots
+memory 0xd4000 96k
+# Debug level, so you know how to get more info for maintainers. Put it
+# in /etc/pccard.conf
+#debuglevel 4
+
+########## an ##########
+
+# Aironet PC4500 2Mbps 802.11 wireless NIC
+card "Aironet" "PC4500"
+ config 0x5 "an0" ?
+ config 0x5 "an1" ?
+ config 0x5 "an2" ?
+
+# Aironet PC4800 11Mbps 802.11 wireless NIC
+card "Aironet" "PC4800"
+ config 0x5 "an0" ?
+ config 0x5 "an1" ?
+ config 0x5 "an2" ?
+
+# Aironet 340 Series 11Mbps 802.11 wireless NIC
+card "Cisco Systems" "340 Series Wireless LAN Adapter"
+ config auto "an0" ?
+ config auto "an1" ?
+ config auto "an2" ?
+
+# Aironet 350 Series 11Mbps 802.11 wireless NIC
+card "Cisco Systems" "350 Series Wireless LAN Adapter"
+ config auto "an0" ?
+ config auto "an1" ?
+ config auto "an2" ?
+
+# Xircom sells a rebaded unit
+card "Xircom" "Wireless Ethernet Adapter"
+ config 0x5 "an0" ?
+ config 0x5 "an1" ?
+ config 0x5 "an2" ?
+
+########## wi ##########
+
+# OEM ID 0x5 unlabelled PRISM2.5 card
+card " " "IEEE 802.11 Wireless LAN/PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# 3com 3crwe737A AirConnect Wireless LAN PC Card
+card "3Com" "3CRWE737A AirConnect Wireless LAN PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Accton airDirect WN3301
+card "Accton" "IEEE802.11 PC Card Adapter"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Actiontec PRISM wireless
+card "ACTIONTEC" "PRISM Wireless LAN PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Addtron AWP-100
+card "Addtron" "AWP-100 Wireless PCMCIA"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# ADLINK340APC
+card "ADTEC" "ADLINK/340C"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Home Wireless Networks
+card "AirWay" "802.11 Adapter (PCMCIA)"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Allied Telesis WR211PCM
+card "Allied Telesis K.K." "WR211PCM"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Avaya Wireless PC Card
+card "Avaya Communication" "Avaya Wireless PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Belkin wireless card
+card "Belkin" "11Mbps Wireless Notebook Network Adapter"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# BreezeNET
+card "BreezeNET" "PC-DS.11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Buffalo WLI-CF-S11G
+card "BUFFALO" "WLI-CF-S11G"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Melco Airconnect 3.3V version
+card "BUFFALO" "WLI-PCM-S11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Melco Airconnect (128bit WEP)
+card "BUFFALO" "WLI-PCM-L11G"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Cabletron RoamAbout, WaveLAN/IEEE clone
+card "Cabletron" "RoamAbout 802.11 DS"
+ config 0x1 "wi0" ?
+ config 0x1 "wi1" ?
+ config 0x1 "wi2" ?
+
+# Compaq WL100
+card "Compaq" "WL100_11Mbps_Wireless_PC_Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Compaq WL110
+card "Compaq" "Compaq WL110 PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Compaq WL200
+card "Compaq" "WL200_11Mbps_Wireless_PCI_Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Compaq WL200 (might be wrong)
+card "Compaq" "Compaq WL200_11Mbps_Wireless_PCI_Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Corega KK Wireless LAN PCC-11
+card "corega K.K." "Wireless LAN PCC-11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Corega KK Wireless LAN PCCA-11
+card "corega K.K." "Wireless LAN PCCA-11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Corega KK Wireless LAN PCCB-11
+card "corega_K.K." "Wireless_LAN_PCCB-11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Corega KK Wireless LAN PCCL-11
+card "corega" "WL PCCL-11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# D Link DWL-650 11Mbps WLAN Card
+card "D" "Link DWL-650 11Mbps WLAN Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# DLink Air DWL-660 Wireless PC Card
+card "D-Link" "D-Link Air DWL-660 Wireless PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Dell TrueMobile (OEMed Lucent WaveLAN/IEEE)
+card "Dell" "TrueMobile 1150 Series PC Card"
+ config 0x1 "wi0" ?
+ config 0x1 "wi1" ?
+ config 0x1 "wi2" ?
+
+# ELECOM Air@Hawk/LD-WL11/PCC (0.7.5)
+card "ELECOM" "Air@Hark/LD-WL11/PCC"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# ELECOM Air@Hawk/LD-WL11/PCC (0.7.6 and later)
+card "ELECOM" "Air@Hawk/LD-WL11/PCC"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# ELSA Air Lancer
+card "ELSA" "AirLancer MC-11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Fujitsu Siemens CONNECT2AIR WLAN C-1100 CF-Card
+card "Fujitsu Siemens Computers" "CONNECT2AIR WLAN C-1100 CF-Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# PLANEX GeoWave/GW-NS11S
+card "Geowave" "GW-NS11S"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Linksys Instant Wireless WPC11
+card "/Instant Wireless */" " Network PC CARD"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Intel PRO/Wireless 2011 LAN PC Card
+card "Intel" "PRO/Wireless 2011 LAN PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# ICOM SL-1100
+card "ICOM" "SL-1100"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# OEM PRISM cards
+card "INTERSIL" "HFA384x/IEEE"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# IO Data WN-B11/PCM
+card "IO DATA" "WNB11PCM"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# IBM's rebadged Lucent WaveLAN/IEEE. The FCC IDs are identical to
+# those for the Lucent card, so presumably everything else is as well.
+card "IBM Corporation" "IBM High Rate Wireless LAN PC Card"
+ config 0x1 "wi0" ?
+ config 0x1 "wi1" ?
+ config 0x1 "wi2" ?
+
+# Lucent WaveLAN/IEEE
+card "Lucent Technologies" "WaveLAN/IEEE"
+ config 0x1 "wi0" ?
+ config 0x1 "wi1" ?
+ config 0x1 "wi2" ?
+
+# Melco Airconnect
+card "MELCO" "WLI-PCM-L11"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# nanospeed card of some flavor.
+card "NANOSPEED" "HFA384x/IEEE"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# NCR WaveLAN/IEEE
+card "NCR" "WaveLAN/IEEE"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# NEC Wireless Card CMZ-RT-WP
+card "NEC" "Wireless Card CMZ-RT-WP"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# NEC WL11C (PC-WL/11C)
+card "NEC Aterm" "WL11C (PC-WL/11C)"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# NEC Corporation PK-WL001
+card "NEC Corporation" "Wireless PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Netgear MA401
+card "NETGEAR MA401 Wireless PC" "Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Netgear MA401RA
+card "NETGEAR MA401RA Wireless PC" "Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Nortel eMobility
+card "Nortel Networks" "emobility 802.11 Wireless LAN PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Generic PRISM2.5 card
+card "PCMCIA" "11M WLAN Card v2.5"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# PLANEX GeoWave/GW-NS110
+card "PLANEX" "GeoWave/GW-NS110"
+ config 0x1 "wi0" ?
+ config 0x1 "wi1" ?
+ config 0x1 "wi2" ?
+
+# PLANEX GW-NS11H
+card "PLANEX" "GW-NS11H Wireless LAN PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Proxim Harmony
+card "PROXIM" "Harmony 802.11b/LAN PC CARD"
+ config 0x1 "wi0" ?
+ config 0x1 "wi1" ?
+ config 0x1 "wi2" ?
+
+# Proxim RangeLAN-DS (OEM of Zcommax - Prism2 card)
+card "PROXIM" "RangeLAN-DS/LAN PC CARD"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# SAMSUNG SWL-2000P PCI Card
+card "SAMSUNG" "11Mbps WLAN PCI Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# SMC's SMC2632W (also matches the 3.3V SMC2602W)
+card "SMC" "SMC2632W"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Sony PCWA-C100 WaveLAN
+card "Sony Corporation" "PCWA-C100"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# German Telekom T-Sinus 130card, unknown original manufactor
+card "T-Sinus" "130card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# TDK LAK-CD011WL
+card "TDK" "LAK-CD011WL for Wireless LAN"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Linksys Instant Wireless WPC11 v2.5
+card "The Linksys Group, Inc." "Instant Wireless Network PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Toshibas wireless lan card
+card "TOSHIBA" "Wireless LAN Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# U.S. Robotics Wireless Card 2410
+card "U.S. Robotics" "IEEE 802.11b PC-CARD"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Taiwanese Blue Concentric Circle CF Wireless LAN Model WL-379F
+# This is a card sold in Taiwan.
+card "Wireless LAN" "11Mbps PC Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# Wisecom WS-WP100W
+card "OEM" "PRISM25 IEEE 802.11 PC-Card"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# YIS YWL-11B
+card "YIS Corp." "YWL-11b"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
+
+# ZoomAir 802.11
+card "ZoomAir 11Mbps High" "Rate wireless Networking"
+ config auto "wi0" ?
+ config auto "wi1" ?
+ config auto "wi2" ?
diff --git a/etc/platform b/etc/platform
new file mode 100644
index 0000000..f964569
--- /dev/null
+++ b/etc/platform
@@ -0,0 +1 @@
+net45xx
diff --git a/etc/protocols b/etc/protocols
new file mode 100644
index 0000000..20e2741
--- /dev/null
+++ b/etc/protocols
@@ -0,0 +1,146 @@
+#
+# Internet protocols
+#
+# $FreeBSD: src/etc/protocols,v 1.13.2.3 2002/02/27 03:39:00 dd Exp $
+# from: @(#)protocols 5.1 (Berkeley) 4/17/89
+#
+# See also http://www.iana.org/assignments/protocol-numbers
+#
+ip 0 IP # internet protocol, pseudo protocol number
+#hopopt 0 HOPOPT # hop-by-hop options for ipv6
+icmp 1 ICMP # internet control message protocol
+igmp 2 IGMP # internet group management protocol
+ggp 3 GGP # gateway-gateway protocol
+ipencap 4 IP-ENCAP # IP encapsulated in IP (officially ``IP'')
+st2 5 ST2 # ST2 datagram mode (RFC 1819)
+tcp 6 TCP # transmission control protocol
+cbt 7 CBT # CBT, Tony Ballardie <A.Ballardie@cs.ucl.ac.uk>
+egp 8 EGP # exterior gateway protocol
+igp 9 IGP # any private interior gateway (Cisco: for IGRP)
+bbn-rcc 10 BBN-RCC-MON # BBN RCC Monitoring
+nvp 11 NVP-II # Network Voice Protocol
+pup 12 PUP # PARC universal packet protocol
+argus 13 ARGUS # ARGUS
+emcon 14 EMCON # EMCON
+xnet 15 XNET # Cross Net Debugger
+chaos 16 CHAOS # Chaos
+udp 17 UDP # user datagram protocol
+mux 18 MUX # Multiplexing protocol
+dcn 19 DCN-MEAS # DCN Measurement Subsystems
+hmp 20 HMP # host monitoring protocol
+prm 21 PRM # packet radio measurement protocol
+xns-idp 22 XNS-IDP # Xerox NS IDP
+trunk-1 23 TRUNK-1 # Trunk-1
+trunk-2 24 TRUNK-2 # Trunk-2
+leaf-1 25 LEAF-1 # Leaf-1
+leaf-2 26 LEAF-2 # Leaf-2
+rdp 27 RDP # "reliable datagram" protocol
+irtp 28 IRTP # Internet Reliable Transaction Protocol
+iso-tp4 29 ISO-TP4 # ISO Transport Protocol Class 4
+netblt 30 NETBLT # Bulk Data Transfer Protocol
+mfe-nsp 31 MFE-NSP # MFE Network Services Protocol
+merit-inp 32 MERIT-INP # MERIT Internodal Protocol
+sep 33 SEP # Sequential Exchange Protocol
+3pc 34 3PC # Third Party Connect Protocol
+idpr 35 IDPR # Inter-Domain Policy Routing Protocol
+xtp 36 XTP # Xpress Tranfer Protocol
+ddp 37 DDP # Datagram Delivery Protocol
+idpr-cmtp 38 IDPR-CMTP # IDPR Control Message Transport Proto
+tp++ 39 TP++ # TP++ Transport Protocol
+il 40 IL # IL Transport Protocol
+ipv6 41 IPV6 # ipv6
+sdrp 42 SDRP # Source Demand Routing Protocol
+ipv6-route 43 IPV6-ROUTE # routing header for ipv6
+ipv6-frag 44 IPV6-FRAG # fragment header for ipv6
+idrp 45 IDRP # Inter-Domain Routing Protocol
+rsvp 46 RSVP # Resource ReSerVation Protocol
+gre 47 GRE # Generic Routing Encapsulation
+mhrp 48 MHRP # Mobile Host Routing Protocol
+bna 49 BNA # BNA
+esp 50 ESP # encapsulating security payload
+ah 51 AH # authentication header
+i-nlsp 52 I-NLSP # Integrated Net Layer Security TUBA
+swipe 53 SWIPE # IP with Encryption
+narp 54 NARP # NBMA Address Resolution Protocol
+mobile 55 MOBILE # IP Mobility
+tlsp 56 TLSP # Transport Layer Security Protocol
+skip 57 SKIP # SKIP
+ipv6-icmp 58 IPV6-ICMP # ICMP for IPv6
+ipv6-nonxt 59 IPV6-NONXT # no next header for ipv6
+ipv6-opts 60 IPV6-OPTS # destination options for ipv6
+# 61 # any host internal protocol
+cftp 62 CFTP # CFTP
+# 63 # any local network
+sat-expak 64 SAT-EXPAK # SATNET and Backroom EXPAK
+kryptolan 65 KRYPTOLAN # Kryptolan
+rvd 66 RVD # MIT Remote Virtual Disk Protocol
+ippc 67 IPPC # Internet Pluribus Packet Core
+# 68 # any distributed file system
+sat-mon 69 SAT-MON # SATNET Monitoring
+visa 70 VISA # VISA Protocol
+ipcv 71 IPCV # Internet Packet Core Utility
+cpnx 72 CPNX # Computer Protocol Network Executive
+cphb 73 CPHB # Computer Protocol Heart Beat
+wsn 74 WSN # Wang Span Network
+pvp 75 PVP # Packet Video Protocol
+br-sat-mon 76 BR-SAT-MON # Backroom SATNET Monitoring
+sun-nd 77 SUN-ND # SUN ND PROTOCOL-Temporary
+wb-mon 78 WB-MON # WIDEBAND Monitoring
+wb-expak 79 WB-EXPAK # WIDEBAND EXPAK
+iso-ip 80 ISO-IP # ISO Internet Protocol
+vmtp 81 VMTP # Versatile Message Transport
+secure-vmtp 82 SECURE-VMTP # SECURE-VMTP
+vines 83 VINES # VINES
+ttp 84 TTP # TTP
+nsfnet-igp 85 NSFNET-IGP # NSFNET-IGP
+dgp 86 DGP # Dissimilar Gateway Protocol
+tcf 87 TCF # TCF
+eigrp 88 EIGRP # Enhanced Interior Routing Protocol (Cisco)
+ospf 89 OSPFIGP # Open Shortest Path First IGP
+sprite-rpc 90 Sprite-RPC # Sprite RPC Protocol
+larp 91 LARP # Locus Address Resolution Protocol
+mtp 92 MTP # Multicast Transport Protocol
+ax.25 93 AX.25 # AX.25 Frames
+ipip 94 IPIP # Yet Another IP encapsulation
+micp 95 MICP # Mobile Internetworking Control Pro.
+scc-sp 96 SCC-SP # Semaphore Communications Sec. Pro.
+etherip 97 ETHERIP # Ethernet-within-IP Encapsulation
+encap 98 ENCAP # Yet Another IP encapsulation
+# 99 # any private encryption scheme
+gmtp 100 GMTP # GMTP
+ifmp 101 IFMP # Ipsilon Flow Management Protocol
+pnni 102 PNNI # PNNI over IP
+pim 103 PIM # Protocol Independent Multicast
+aris 104 ARIS # ARIS
+scps 105 SCPS # SCPS
+qnx 106 QNX # QNX
+a/n 107 A/N # Active Networks
+ipcomp 108 IPComp # IP Payload Compression Protocol
+snp 109 SNP # Sitara Networks Protocol
+compaq-peer 110 Compaq-Peer # Compaq Peer Protocol
+ipx-in-ip 111 IPX-in-IP # IPX in IP
+vrrp 112 VRRP # Virtual Router Redundancy Protocol
+pgm 113 PGM # PGM Reliable Transport Protocol
+# 114 # any 0-hop protocol
+l2tp 115 L2TP # Layer Two Tunneling Protocol
+ddx 116 DDX # D-II Data Exchange
+iatp 117 IATP # Interactive Agent Transfer Protocol
+st 118 ST # Schedule Transfer
+srp 119 SRP # SpectraLink Radio Protocol
+uti 120 UTI # UTI
+smp 121 SMP # Simple Message Protocol
+sm 122 SM # SM
+ptp 123 PTP # Performance Transparency Protocol
+isis 124 ISIS # ISIS over IPv4
+fire 125 FIRE
+crtp 126 CRTP # Combat Radio Transport Protocol
+crudp 127 CRUDP # Combat Radio User Datagram
+sscopmce 128 SSCOPMCE
+iplt 129 IPLT
+sps 130 SPS # Secure Packet Shield
+pipe 131 PIPE # Private IP Encapsulation within IP
+sctp 132 SCTP # Stream Control Transmission Protocol
+fc 133 FC # Fibre Channel
+# 134-254 # Unassigned
+divert 254 DIVERT # Divert pseudo-protocol [non IANA]
+# 255 # Reserved
diff --git a/etc/pubkey.pem b/etc/pubkey.pem
new file mode 100644
index 0000000..f935cb5
--- /dev/null
+++ b/etc/pubkey.pem
@@ -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 100755
index 0000000..af4b2f5
--- /dev/null
+++ b/etc/rc
@@ -0,0 +1,62 @@
+#!/bin/sh
+
+# /etc/rc
+# part of m0n0wall (http://neon1.net/m0n0wall)
+#
+# Copyright (C) 2003-2004 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
+
+/sbin/mount -a || fsck -y && mount -a
+
+set -T
+trap "echo 'Reboot interrupted'; exit 1" 3
+
+# make some directories in /var
+mkdir /var/run /var/log /var/etc /var/db/ipf 2>/dev/null
+chmod 0755 /var/db/ipf
+rm -rf /var/log/*
+
+# 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
+clog -i -s 32768 /var/log/vpn.log
+chmod 0600 /var/log/system.log /var/log/filter.log /var/log/dhcpd.log /var/log/vpn.log
+
+adjkerntz -i
+
+#mount_devfs devfs /dev
+
+# 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
+
+echo
+echo "Starting LiveBSD.com's m0n0wall 1.2b2 PF ..."
+echo
+
+# let the PHP-based configuration subsystem set up the system now
+/etc/rc.bootup
+
+/usr/sbin/pfctl -f /tmp/rules.debug
+/usr/sbin/pfctl -e
+
+echo Starting Secure Shell Services ...
+/etc/sshd
+
+exit 0
+
diff --git a/etc/rc.banner b/etc/rc.banner
new file mode 100755
index 0000000..0f5b8e5
--- /dev/null
+++ b/etc/rc.banner
@@ -0,0 +1,59 @@
+#!/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 LiveBSD.com's m0n0wall version {$version}
+ Copyright 2004 Scott Ullrich. All rights reserved.
+ Originally based on m0n0wall, version 1.2b1
+ m0n0wall is Copyright 2002-2004 by Manuel Kasper. All rights reserved
+
+ LAN IP address: {$config['interfaces']['lan']['ipaddr']}
+
+ Port configurations:
+
+ 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/etc/rc.bootup b/etc/rc.bootup
new file mode 100755
index 0000000..04f8266
--- /dev/null
+++ b/etc/rc.bootup
@@ -0,0 +1,147 @@
+#!/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();
+
+ /* run any early shell commands specified in config.xml */
+ system_do_shell_commands(1);
+
+ /* save dmesg output to file */
+ system_dmesg_save();
+
+ /* 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 */
+ if (!in_array($g['platform'], $g['nopccard_platforms']))
+ system_pccard_start();
+
+ /* establish ipfilter ruleset */
+ filter_configure();
+
+ /* configure loopback interface */
+ interfaces_loopback_configure();
+
+ /* set up VLAN virtual interfaces */
+ interfaces_vlan_configure();
+
+ /* set up LAN interface */
+ interfaces_lan_configure();
+
+ /* set up WAN interface */
+ interfaces_wan_configure();
+
+ /* set up Optional interfaces */
+ interfaces_optional_configure();
+
+ /* start OpenVPN server & clients */
+ ovpn_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();
+
+ /* start the captive portal */
+ captiveportal_configure();
+
+ /* execute the rc scripts of extensions */
+ system_do_extensions();
+
+ /* run any shell commands specified in config.xml */
+ system_do_shell_commands();
+
+ /* done */
+ unlink("{$g['varrun_path']}/booting");
+?>
diff --git a/etc/rc.dyndns.storecache b/etc/rc.dyndns.storecache
new file mode 100755
index 0000000..180662e
--- /dev/null
+++ b/etc/rc.dyndns.storecache
@@ -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 100755
index 0000000..56fc7a4
--- /dev/null
+++ b/etc/rc.firmware
@@ -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 100755
index 0000000..bece644
--- /dev/null
+++ b/etc/rc.initial
@@ -0,0 +1,76 @@
+#!/bin/sh
+
+# /etc/rc.initial
+# part of m0n0wall (http://neon1.net/m0n0wall)
+#
+# Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
+# All rights reserved.
+
+# make sure the user can't kill us by pressing Ctrl-C
+trap : 2
+trap : 3
+trap : 4
+
+if [ -r /var/etc/disableconsole ]; then
+
+while : ; do
+
+echo
+echo
+echo "*** Console menu disabled. ***"
+echo
+
+read tmp
+
+done
+
+else
+
+# endless loop
+while : ; do
+
+/etc/rc.banner
+
+# display a cheap menu
+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 "6) Ping host"
+echo "7) Shell"
+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
+ ;;
+6)
+ /etc/rc.initial.ping
+ ;;
+7)
+ set prompt = "\n`/bin/hostname -s`# "
+ /bin/sh
+ ;;
+esac
+
+done
+
+fi
diff --git a/etc/rc.initial.defaults b/etc/rc.initial.defaults
new file mode 100755
index 0000000..8e33fd2
--- /dev/null
+++ b/etc/rc.initial.defaults
@@ -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/etc/rc.initial.password b/etc/rc.initial.password
new file mode 100755
index 0000000..7859e2c
--- /dev/null
+++ b/etc/rc.initial.password
@@ -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/etc/rc.initial.ping b/etc/rc.initial.ping
new file mode 100755
index 0000000..d069566
--- /dev/null
+++ b/etc/rc.initial.ping
@@ -0,0 +1,47 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+ rc.initial.ping
+ 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 "\nEnter a host name or IP address: ";
+
+ $pinghost = chop(fgets($fp));
+ if ($pinghost) {
+ echo "\n";
+ passthru("/sbin/ping -c 3 -n " . escapeshellarg($pinghost));
+ echo "\nPress ENTER to continue.\n";
+ fgets($fp);
+ }
+?>
diff --git a/etc/rc.initial.reboot b/etc/rc.initial.reboot
new file mode 100755
index 0000000..053d492
--- /dev/null
+++ b/etc/rc.initial.reboot
@@ -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/etc/rc.initial.setlanip b/etc/rc.initial.setlanip
new file mode 100755
index 0000000..99fd922
--- /dev/null
+++ b/etc/rc.initial.setlanip
@@ -0,0 +1,117 @@
+#!/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";
+ }
+
+ if (isset($config['system']['webgui']['noantilockout'])) {
+ echo "\nNote: the anti-lockout rule on LAN has been re-enabled.\n";
+ unset($config['system']['webgui']['noantilockout']);
+ }
+
+ 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/etc/rc.initial.setports b/etc/rc.initial.setports
new file mode 100755
index 0000000..049879a
--- /dev/null
+++ b/etc/rc.initial.setports
@@ -0,0 +1,303 @@
+#!/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
+
+Do you want to set up VLANs first?
+If you're not going to use VLANs, or only for optional interfaces, you
+should say no here and use the webGUI to configure VLANs later, if required.
+
+Do you want to set up VLANs now? (y/n)
+EOD;
+
+ if (strcasecmp(chop(fgets($fp)), "y") == 0)
+ vlan_setup();
+
+ if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
+
+ echo "\n\nVLAN interfaces:\n\n";
+ $i = 0;
+ foreach ($config['vlans']['vlan'] as $vlan) {
+
+ echo sprintf("% -8s%s\n", "vlan{$i}",
+ "VLAN tag {$vlan['tag']}, interface {$vlan['if']}");
+
+ $iflist['vlan' . $i] = array();
+ $i++;
+ }
+ }
+
+ 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;
+ }
+
+ function vlan_setup() {
+ global $iflist, $config, $g, $fp;
+
+ if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
+
+ echo <<<EOD
+
+WARNING: all existing VLANs will be cleared if you proceed!
+
+Do you want to proceed? (y/n)
+EOD;
+
+ if (strcasecmp(chop(fgets($fp)), "y") != 0)
+ return;
+ }
+
+ $config['vlans']['vlan'] = array();
+ echo "\n";
+
+ while (1) {
+ $vlan = array();
+
+ echo "\nEnter the parent interface name for the new VLAN (or nothing if finished): ";
+ $vlan['if'] = chop(fgets($fp));
+
+ if ($vlan['if']) {
+ if (!array_key_exists($vlan['if'], $iflist)) {
+ echo "\nInvalid interface name '{$vlan['if']}'\n";
+ continue;
+ }
+ } else {
+ break;
+ }
+
+ echo "Enter the VLAN tag (1-4094): ";
+ $vlan['tag'] = chop(fgets($fp));
+
+ if (!is_numericint($vlan['tag']) || ($vlan['tag'] < 1) || ($vlan['tag'] > 4094)) {
+ echo "\nInvalid VLAN tag '{$vlan['tag']}'\n";
+ continue;
+ }
+
+ $config['vlans']['vlan'][] = $vlan;
+ }
+ }
+?>
diff --git a/etc/rc.newwanip b/etc/rc.newwanip
new file mode 100755
index 0000000..5328028
--- /dev/null
+++ b/etc/rc.newwanip
@@ -0,0 +1,83 @@
+#!/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);
+ }
+ */
+
+ $curwanip = get_current_wan_address();
+
+ /* dhclient or MPD told us that the IP address has changed;
+ let's see if that's really true to avoid reloading things
+ when it's not really necessary (dhclient likes to
+ execute its dhclient-exit-hooks also on renewals)
+ */
+ if (file_exists("{$g['vardb_path']}/wanip")) {
+ $oldwanip = chop(file_get_contents("{$g['vardb_path']}/wanip"));
+
+ if ($curwanip == $oldwanip)
+ return 0; /* nothing to do */
+ }
+
+ /* resync ipfilter */
+ filter_resync();
+
+ /* flush NAT table */
+ filter_flush_nat_table();
+
+ /* reconfigure IPsec tunnels */
+ vpn_ipsec_configure(true);
+
+ /* regenerate resolv.conf if DNS overrides are allowed or the BigPond
+ client is enabled */
+ if (isset($config['system']['dnsallowoverride']) ||
+ ($config['interfaces']['wan']['ipaddr'] == "bigpond"))
+ system_resolvconf_generate(true);
+
+ /* fire up the BigPond client, if necessary */
+ if ($config['interfaces']['wan']['ipaddr'] == "bigpond")
+ interfaces_wan_bigpond_configure($curwanip);
+
+ /* write current WAN IP to file */
+ $fd = @fopen("{$g['vardb_path']}/wanip", "w");
+ if ($fd) {
+ fwrite($fd, $curwanip);
+ fclose($fd);
+ }
+?>
diff --git a/etc/rc.prunecaptiveportal b/etc/rc.prunecaptiveportal
new file mode 100755
index 0000000..108b029
--- /dev/null
+++ b/etc/rc.prunecaptiveportal
@@ -0,0 +1,37 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+ rc.prunecaptiveportal
+ 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");
+
+ captiveportal_prune_old();
+?>
diff --git a/etc/rc.reboot b/etc/rc.reboot
new file mode 100755
index 0000000..2b3eb08
--- /dev/null
+++ b/etc/rc.reboot
@@ -0,0 +1,5 @@
+#!/bin/sh
+
+sleep 1
+
+/sbin/reboot
diff --git a/etc/rc.shutdown b/etc/rc.shutdown
new file mode 100755
index 0000000..1deb79a
--- /dev/null
+++ b/etc/rc.shutdown
@@ -0,0 +1,17 @@
+#!/bin/sh
+
+stty status '^T'
+
+# Set shell to ignore SIGINT (2), but not children;
+# shell catches SIGQUIT (3) and returns to single user after fsck.
+trap : 2
+trap : 3 # shouldn't be needed
+
+HOME=/
+PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin
+export HOME PATH
+
+# Insert other shutdown procedures here
+
+exit 0
+
diff --git a/etc/services b/etc/services
new file mode 100644
index 0000000..c583eac
--- /dev/null
+++ b/etc/services
@@ -0,0 +1,2106 @@
+#
+# Network services, Internet style
+#
+# Note that it is presently the policy of IANA to assign a single well-known
+# port number for both TCP and UDP; hence, most entries here have two entries
+# even if the protocol doesn't support UDP operations.
+#
+# The latest IANA port assignments can be gotten from
+#
+# http://www.iana.org/assignments/port-numbers
+#
+# The Well Known Ports are those from 0 through 1023.
+# The Registered Ports are those from 1024 through 49151
+# The Dynamic and/or Private Ports are those from 49152 through 65535
+#
+# Kerberos services are for Kerberos v4, and are unofficial. Sites running
+# v5 should uncomment v5 entries and comment v4 entries.
+#
+# $FreeBSD: src/etc/services,v 1.62.2.12 2003/02/01 16:48:17 schweikh Exp $
+# From: @(#)services 5.8 (Berkeley) 5/9/91
+#
+# WELL KNOWN PORT NUMBERS
+#
+rtmp 1/ddp #Routing Table Maintenance Protocol
+tcpmux 1/tcp #TCP Port Service Multiplexer
+tcpmux 1/udp #TCP Port Service Multiplexer
+nbp 2/ddp #Name Binding Protocol
+compressnet 2/tcp #Management Utility
+compressnet 2/udp #Management Utility
+compressnet 3/tcp #Compression Process
+compressnet 3/udp #Compression Process
+echo 4/ddp #AppleTalk Echo Protocol
+rje 5/tcp #Remote Job Entry
+rje 5/udp #Remote Job Entry
+zip 6/ddp #Zone Information Protocol
+echo 7/tcp
+echo 7/udp
+discard 9/tcp sink null
+discard 9/udp sink null
+systat 11/tcp users #Active Users
+systat 11/udp users #Active Users
+daytime 13/tcp
+daytime 13/udp
+qotd 17/tcp quote #Quote of the Day
+qotd 17/udp quote #Quote of the Day
+msp 18/tcp #Message Send Protocol
+msp 18/udp #Message Send Protocol
+chargen 19/tcp ttytst source #Character Generator
+chargen 19/udp ttytst source #Character Generator
+ftp-data 20/tcp #File Transfer [Default Data]
+ftp-data 20/udp #File Transfer [Default Data]
+ftp 21/tcp #File Transfer [Control]
+ftp 21/udp #File Transfer [Control]
+ssh 22/tcp #Secure Shell Login
+ssh 22/udp #Secure Shell Login
+telnet 23/tcp
+telnet 23/udp
+# 24/tcp any private mail system
+# 24/udp any private mail system
+smtp 25/tcp mail #Simple Mail Transfer
+smtp 25/udp mail #Simple Mail Transfer
+nsw-fe 27/tcp #NSW User System FE
+nsw-fe 27/udp #NSW User System FE
+msg-icp 29/tcp #MSG ICP
+msg-icp 29/udp #MSG ICP
+msg-auth 31/tcp #MSG Authentication
+msg-auth 31/udp #MSG Authentication
+dsp 33/tcp #Display Support Protocol
+dsp 33/udp #Display Support Protocol
+# 35/tcp any private printer server
+# 35/udp any private printer server
+time 37/tcp timserver
+time 37/udp timserver
+rap 38/tcp #Route Access Protocol
+rap 38/udp #Route Access Protocol
+rlp 39/tcp resource #Resource Location Protocol
+rlp 39/udp resource #Resource Location Protocol
+graphics 41/tcp
+graphics 41/udp
+nameserver 42/tcp name #Host Name Server
+nameserver 42/udp name #Host Name Server
+nicname 43/tcp whois
+nicname 43/udp whois
+mpm-flags 44/tcp #MPM FLAGS Protocol
+mpm-flags 44/udp #MPM FLAGS Protocol
+mpm 45/tcp #Message Processing Module [recv]
+mpm 45/udp #Message Processing Module [recv]
+mpm-snd 46/tcp #MPM [default send]
+mpm-snd 46/udp #MPM [default send]
+ni-ftp 47/tcp #NI FTP
+ni-ftp 47/udp #NI FTP
+auditd 48/tcp #Digital Audit Daemon
+auditd 48/udp #Digital Audit Daemon
+tacacs 49/tcp #Login Host Protocol (TACACS)
+tacacs 49/udp #Login Host Protocol (TACACS)
+re-mail-ck 50/tcp #Remote Mail Checking Protocol
+re-mail-ck 50/udp #Remote Mail Checking Protocol
+la-maint 51/tcp #IMP Logical Address Maintenance
+la-maint 51/udp #IMP Logical Address Maintenance
+xns-time 52/tcp #XNS Time Protocol
+xns-time 52/udp #XNS Time Protocol
+domain 53/tcp #Domain Name Server
+domain 53/udp #Domain Name Server
+xns-ch 54/tcp #XNS Clearinghouse
+xns-ch 54/udp #XNS Clearinghouse
+isi-gl 55/tcp #ISI Graphics Language
+isi-gl 55/udp #ISI Graphics Language
+xns-auth 56/tcp #XNS Authentication
+xns-auth 56/udp #XNS Authentication
+mtp 57/tcp # deprecated
+#PROBLEMS!==============================================================
+# 57/tcp any private terminal access
+#PROBLEMS!==============================================================
+# 57/udp any private terminal access
+xns-mail 58/tcp #XNS Mail
+xns-mail 58/udp #XNS Mail
+# 59/tcp any private file service
+# 59/udp any private file service
+ni-mail 61/tcp #NI MAIL
+ni-mail 61/udp #NI MAIL
+acas 62/tcp #ACA Services
+acas 62/udp #ACA Services
+whois++ 63/tcp
+whois++ 63/udp
+covia 64/tcp #Communications Integrator (CI)
+covia 64/udp #Communications Integrator (CI)
+tacacs-ds 65/tcp #TACACS-Database Service
+tacacs-ds 65/udp #TACACS-Database Service
+sql*net 66/tcp #Oracle SQL*NET
+sql*net 66/udp #Oracle SQL*NET
+bootps 67/tcp dhcps #Bootstrap Protocol Server
+bootps 67/udp dhcps #Bootstrap Protocol Server
+bootpc 68/tcp dhcpc #Bootstrap Protocol Client
+bootpc 68/udp dhcpc #Bootstrap Protocol Client
+tftp 69/tcp #Trivial File Transfer
+tftp 69/udp #Trivial File Transfer
+gopher 70/tcp
+gopher 70/udp
+netrjs-1 71/tcp #Remote Job Service
+netrjs-1 71/udp #Remote Job Service
+netrjs-2 72/tcp #Remote Job Service
+netrjs-2 72/udp #Remote Job Service
+netrjs-3 73/tcp #Remote Job Service
+netrjs-3 73/udp #Remote Job Service
+netrjs-4 74/tcp #Remote Job Service
+netrjs-4 74/udp #Remote Job Service
+# 75/tcp any private dial out service
+# 75/udp any private dial out service
+deos 76/tcp #Distributed External Object Store
+deos 76/udp #Distributed External Object Store
+netrjs 77/tcp
+#PROBLEMS!==============================================================
+# 77/tcp any private RJE service
+#PROBLEMS!==============================================================
+# 77/udp any private RJE service
+vettcp 78/tcp
+vettcp 78/udp
+finger 79/tcp
+finger 79/udp
+http 80/tcp www www-http #World Wide Web HTTP
+http 80/udp www www-http #World Wide Web HTTP
+hosts2-ns 81/tcp #HOSTS2 Name Server
+hosts2-ns 81/udp #HOSTS2 Name Server
+xfer 82/tcp #XFER Utility
+xfer 82/udp #XFER Utility
+mit-ml-dev 83/tcp #MIT ML Device
+mit-ml-dev 83/udp #MIT ML Device
+ctf 84/tcp #Common Trace Facility
+ctf 84/udp #Common Trace Facility
+mit-ml-dev 85/tcp #MIT ML Device
+mit-ml-dev 85/udp #MIT ML Device
+mfcobol 86/tcp #Micro Focus Cobol
+mfcobol 86/udp #Micro Focus Cobol
+ttylink 87/tcp
+#PROBLEMS!===========================================================
+# 87/tcp any private terminal link
+#PROBLEMS!===========================================================
+# 87/udp any private terminal link
+kerberos-sec 88/tcp kerberos # krb5 # Kerberos (v5)
+kerberos-sec 88/udp kerberos # krb5 # Kerberos (v5)
+su-mit-tg 89/tcp #SU/MIT Telnet Gateway
+su-mit-tg 89/udp #SU/MIT Telnet Gateway
+dnsix 90/tcp #DNSIX Securit Attribute Token Map
+dnsix 90/udp #DNSIX Securit Attribute Token Map
+mit-dov 91/tcp #MIT Dover Spooler
+mit-dov 91/udp #MIT Dover Spooler
+npp 92/tcp #Network Printing Protocol
+npp 92/udp #Network Printing Protocol
+dcp 93/tcp #Device Control Protocol
+dcp 93/udp #Device Control Protocol
+objcall 94/tcp #Tivoli Object Dispatcher
+objcall 94/udp #Tivoli Object Dispatcher
+supdup 95/tcp
+supdup 95/udp
+dixie 96/tcp #DIXIE Protocol Specification
+dixie 96/udp #DIXIE Protocol Specification
+swift-rvf 97/tcp #Swift Remote Virtural File Protocol
+swift-rvf 97/udp #Swift Remote Virtural File Protocol
+tacnews 98/tcp #TAC News, Unofficial: Red Hat linuxconf
+tacnews 98/udp #TAC News, Unofficial: Red Hat linuxconf
+metagram 99/tcp #Metagram Relay
+metagram 99/udp #Metagram Relay
+newacct 100/tcp #[unauthorized use]
+hostname 101/tcp hostnames #NIC Host Name Server
+hostname 101/udp hostnames #NIC Host Name Server
+iso-tsap 102/tcp tsap #ISO-TSAP Class 0
+iso-tsap 102/udp tsap #ISO-TSAP Class 0
+gppitnp 103/tcp #Genesis Point-to-Point Trans Net
+gppitnp 103/udp #Genesis Point-to-Point Trans Net
+acr-nema 104/tcp #ACR-NEMA Digital Imag. & Comm. 300
+acr-nema 104/udp #ACR-NEMA Digital Imag. & Comm. 300
+csnet-ns 105/tcp cso-ns cso #Mailbox Name Nameserver
+csnet-ns 105/udp cso-ns cso #Mailbox Name Nameserver
+pop3pw 106/tcp 3com-tsmux #Eudora compatible PW changer
+3com-tsmux 106/udp
+rtelnet 107/tcp #Remote Telnet Service
+rtelnet 107/udp #Remote Telnet Service
+snagas 108/tcp #SNA Gateway Access Server
+snagas 108/udp #SNA Gateway Access Server
+pop2 109/tcp postoffice #Post Office Protocol - Version 2
+pop2 109/udp postoffice #Post Office Protocol - Version 2
+pop3 110/tcp #Post Office Protocol - Version 3
+pop3 110/udp #Post Office Protocol - Version 3
+sunrpc 111/tcp rpcbind #SUN Remote Procedure Call
+sunrpc 111/udp rpcbind #SUN Remote Procedure Call
+mcidas 112/tcp #McIDAS Data Transmission Protocol
+mcidas 112/udp #McIDAS Data Transmission Protocol
+auth 113/tcp ident tap #Authentication Service
+auth 113/udp ident tap #Authentication Service
+audionews 114/tcp #Audio News Multicast
+audionews 114/udp #Audio News Multicast
+sftp 115/tcp #Simple File Transfer Protocol
+sftp 115/udp #Simple File Transfer Protocol
+ansanotify 116/tcp #ANSA REX Notify
+ansanotify 116/udp #ANSA REX Notify
+uucp-path 117/tcp #UUCP Path Service
+uucp-path 117/udp #UUCP Path Service
+sqlserv 118/tcp #SQL Services
+sqlserv 118/udp #SQL Services
+nntp 119/tcp usenet #Network News Transfer Protocol
+nntp 119/udp usenet #Network News Transfer Protocol
+cfdptkt 120/tcp
+cfdptkt 120/udp
+erpc 121/tcp #Encore Expedited Remote Pro.Call
+erpc 121/udp #Encore Expedited Remote Pro.Call
+smakynet 122/tcp
+smakynet 122/udp
+ntp 123/tcp #Network Time Protocol
+ntp 123/udp #Network Time Protocol
+ansatrader 124/tcp #ANSA REX Trader
+ansatrader 124/udp #ANSA REX Trader
+locus-map 125/tcp #Locus PC-Interface Net Map Ser
+locus-map 125/udp #Locus PC-Interface Net Map Ser
+unitary 126/tcp #Unisys Unitary Login
+unitary 126/udp #Unisys Unitary Login
+locus-con 127/tcp #Locus PC-Interface Conn Server
+locus-con 127/udp #Locus PC-Interface Conn Server
+gss-xlicen 128/tcp #GSS X License Verification
+gss-xlicen 128/udp #GSS X License Verification
+pwdgen 129/tcp #Password Generator Protocol
+pwdgen 129/udp #Password Generator Protocol
+cisco-fna 130/tcp #cisco FNATIVE
+cisco-fna 130/udp #cisco FNATIVE
+cisco-tna 131/tcp #cisco TNATIVE
+cisco-tna 131/udp #cisco TNATIVE
+cisco-sys 132/tcp #cisco SYSMAINT
+cisco-sys 132/udp #cisco SYSMAINT
+statsrv 133/tcp #Statistics Service
+statsrv 133/udp #Statistics Service
+ingres-net 134/tcp #INGRES-NET Service
+ingres-net 134/udp #INGRES-NET Service
+loc-srv 135/tcp epmap #Location Service
+loc-srv 135/udp epmap #Location Service
+profile 136/tcp #PROFILE Naming System
+profile 136/udp #PROFILE Naming System
+netbios-ns 137/tcp #NETBIOS Name Service
+netbios-ns 137/udp #NETBIOS Name Service
+netbios-dgm 138/tcp #NETBIOS Datagram Service
+netbios-dgm 138/udp #NETBIOS Datagram Service
+netbios-ssn 139/tcp #NETBIOS Session Service
+netbios-ssn 139/udp #NETBIOS Session Service
+emfis-data 140/tcp #EMFIS Data Service
+emfis-data 140/udp #EMFIS Data Service
+emfis-cntl 141/tcp #EMFIS Control Service
+emfis-cntl 141/udp #EMFIS Control Service
+bl-idm 142/tcp #Britton-Lee IDM
+bl-idm 142/udp #Britton-Lee IDM
+imap 143/tcp imap2 imap4 #Interim Mail Access Protocol v2
+imap 143/udp imap2 imap4 #Interim Mail Access Protocol v2
+NeWS 144/tcp # Window System
+NeWS 144/udp # Window System
+#PROBLEMS!==============================================================
+#uma 144/tcp #Universal Management Architecture
+#uma 144/udp #Universal Management Architecture
+#PROBLEMS!==============================================================
+uaac 145/tcp #UAAC Protocol
+uaac 145/udp #UAAC Protocol
+iso-tp0 146/tcp
+iso-tp0 146/udp
+iso-ip 147/tcp
+iso-ip 147/udp
+cronus 148/tcp jargon #CRONUS-SUPPORT
+cronus 148/udp jargon #CRONUS-SUPPORT
+aed-512 149/tcp #AED 512 Emulation Service
+aed-512 149/udp #AED 512 Emulation Service
+sql-net 150/tcp
+sql-net 150/udp
+hems 151/tcp
+hems 151/udp
+bftp 152/tcp #Background File Transfer Program
+bftp 152/udp #Background File Transfer Program
+sgmp 153/tcp
+sgmp 153/udp
+netsc-prod 154/tcp
+netsc-prod 154/udp
+netsc-dev 155/tcp
+netsc-dev 155/udp
+sqlsrv 156/tcp #SQL Service
+sqlsrv 156/udp #SQL Service
+knet-cmp 157/tcp #KNET/VM Command/Message Protocol
+knet-cmp 157/udp #KNET/VM Command/Message Protocol
+pcmail-srv 158/tcp #PCMail Server
+pcmail-srv 158/udp #PCMail Server
+nss-routing 159/tcp
+nss-routing 159/udp
+sgmp-traps 160/tcp
+sgmp-traps 160/udp
+snmp 161/tcp
+snmp 161/udp
+snmptrap 162/tcp snmp-trap
+snmptrap 162/udp snmp-trap
+cmip-man 163/tcp #CMIP/TCP Manager
+cmip-man 163/udp #CMIP/TCP Manager
+cmip-agent 164/tcp #CMIP/TCP Agent
+smip-agent 164/udp #CMIP/TCP Agent
+xns-courier 165/tcp #Xerox
+xns-courier 165/udp #Xerox
+s-net 166/tcp #Sirius Systems
+s-net 166/udp #Sirius Systems
+namp 167/tcp
+namp 167/udp
+rsvd 168/tcp
+rsvd 168/udp
+send 169/tcp
+send 169/udp
+print-srv 170/tcp #Network PostScript
+print-srv 170/udp #Network PostScript
+multiplex 171/tcp #Network Innovations Multiplex
+multiplex 171/udp #Network Innovations Multiplex
+cl/1 172/tcp #Network Innovations CL/1
+cl/1 172/udp #Network Innovations CL/1
+xyplex-mux 173/tcp
+xyplex-mux 173/udp
+mailq 174/tcp
+mailq 174/udp
+vmnet 175/tcp
+vmnet 175/udp
+genrad-mux 176/tcp
+genrad-mux 176/udp
+xdmcp 177/tcp #X Display Manager Control Protocol
+xdmcp 177/udp #X Display Manager Control Protocol
+NextStep 178/tcp nextstep NeXTStep #NextStep Window Server
+NextStep 178/udp nextstep NeXTStep #NextStep Window Server
+bgp 179/tcp #Border Gateway Protocol
+bgp 179/udp #Border Gateway Protocol
+ris 180/tcp #Intergraph
+ris 180/udp #Intergraph
+unify 181/tcp
+unify 181/udp
+audit 182/tcp #Unisys Audit SITP
+audit 182/udp #Unisys Audit SITP
+ocbinder 183/tcp
+ocbinder 183/udp
+ocserver 184/tcp
+ocserver 184/udp
+remote-kis 185/tcp
+remote-kis 185/udp
+kis 186/tcp #KIS Protocol
+kis 186/udp #KIS Protocol
+aci 187/tcp #Application Communication Interface
+aci 187/udp #Application Communication Interface
+mumps 188/tcp #Plus Five's MUMPS
+mumps 188/udp #Plus Five's MUMPS
+qft 189/tcp #Queued File Transport
+qft 189/udp #Queued File Transport
+gacp 190/tcp #Gateway Access Control Protocol
+gacp 190/udp cacp #Gateway Access Control Protocol
+prospero 191/tcp #Prospero Directory Service
+prospero 191/udp #Prospero Directory Service
+osu-nms 192/tcp #OSU Network Monitoring System
+osu-nms 192/udp #OSU Network Monitoring System
+srmp 193/tcp #Spider Remote Monitoring Protocol
+srmp 193/udp #Spider Remote Monitoring Protocol
+irc 194/tcp #Internet Relay Chat Protocol
+irc 194/udp #Internet Relay Chat Protocol
+dn6-nlm-aud 195/tcp #DNSIX Network Level Module Audit
+dn6-nlm-aud 195/udp #DNSIX Network Level Module Audit
+dn6-smm-red 196/tcp #DNSIX Session Mgt Module Audit Redir
+dn6-smm-red 196/udp #DNSIX Session Mgt Module Audit Redir
+dls 197/tcp #Directory Location Service
+dls 197/udp #Directory Location Service
+dls-mon 198/tcp #Directory Location Service Monitor
+dls-mon 198/udp #Directory Location Service Monitor
+smux 199/tcp
+smux 199/udp
+src 200/tcp #IBM System Resource Controller
+src 200/udp #IBM System Resource Controller
+at-rtmp 201/tcp #AppleTalk Routing Maintenance
+at-rtmp 201/udp #AppleTalk Routing Maintenance
+at-nbp 202/tcp #AppleTalk Name Binding
+at-nbp 202/udp #AppleTalk Name Binding
+at-3 203/tcp #AppleTalk Unused
+at-3 203/udp #AppleTalk Unused
+at-echo 204/tcp #AppleTalk Echo
+at-echo 204/udp #AppleTalk Echo
+at-5 205/tcp #AppleTalk Unused
+at-5 205/udp #AppleTalk Unused
+at-zis 206/tcp #AppleTalk Zone Information
+at-zis 206/udp #AppleTalk Zone Information
+at-7 207/tcp #AppleTalk Unused
+at-7 207/udp #AppleTalk Unused
+at-8 208/tcp #AppleTalk Unused
+at-8 208/udp #AppleTalk Unused
+qmtp 209/tcp #The Quick Mail Transfer Protocol
+qmtp 209/udp #The Quick Mail Transfer Protocol
+#PROBLEMS!==============================================================
+#tam 209/tcp #Trivial Authenticated Mail Protocol
+#tam 209/udp #Trivial Authenticated Mail Protocol
+#PROBLEMS!==============================================================
+z39.50 210/tcp wais #ANSI Z39.50
+z39.50 210/udp wais #ANSI Z39.50
+914c/g 211/tcp #Texas Instruments 914C/G Terminal
+914c/g 211/udp #Texas Instruments 914C/G Terminal
+anet 212/tcp #ATEXSSTR
+anet 212/udp #ATEXSSTR
+ipx 213/tcp
+ipx 213/udp
+vmpwscs 214/tcp
+vmpwscs 214/udp
+softpc 215/tcp #Insignia Solutions
+softpc 215/udp #Insignia Solutions
+CAIlic 216/tcp atls #Computer Associates Int'l License Server
+CAIlic 216/udp atls #Computer Associates Int'l License Server
+dbase 217/tcp #dBASE Unix
+dbase 217/udp #dBASE Unix
+mpp 218/tcp #Netix Message Posting Protocol
+mpp 218/udp #Netix Message Posting Protocol
+uarps 219/tcp #Unisys ARPs
+uarps 219/udp #Unisys ARPs
+#imap3@220 was never used and never should have been allocated. See PR 46294.
+#imap3 220/tcp #Interactive Mail Access Protocol v3
+#imap3 220/udp #Interactive Mail Access Protocol v3
+fln-spx 221/tcp #Berkeley rlogind with SPX auth
+fln-spx 221/udp #Berkeley rlogind with SPX auth
+rsh-spx 222/tcp #Berkeley rshd with SPX auth
+rsh-spx 222/udp #Berkeley rshd with SPX auth
+cdc 223/tcp #Certificate Distribution Center
+cdc 223/udp #Certificate Distribution Center
+direct 242/tcp
+direct 242/udp
+sur-meas 243/tcp #Survey Measurement
+sur-meas 243/udp #Survey Measurement
+dayna 244/tcp
+dayna 244/udp
+link 245/tcp
+link 245/udp
+dsp3270 246/tcp #Display Systems Protocol
+dsp3270 246/udp #Display Systems Protocol
+subntbcst_tftp 247/tcp #subntbcst_tftp
+subntbcst_tftp 247/udp #subntbcst_tftp
+bhfhs 248/tcp
+bhfhs 248/udp
+# 249-255 reserved
+rap 256/tcp
+rap 256/udp
+set 257/tcp #secure electronic transaction
+set 257/udp #secure electronic transaction
+yak-chat 258/tcp #yak winsock personal chat
+yak-chat 258/udp #yak winsock personal chat
+esro-gen 259/tcp #efficient short remote operations
+esro-gen 259/udp #efficient short remote operations
+openport 260/tcp
+openport 260/udp
+nsiiops 261/tcp #iiop name service over tls/ssl
+nsiiops 261/udp #iiop name service over tls/ssl
+arcisdms 262/tcp
+arcisdms 262/udp
+hdap 263/tcp
+hdap 263/udp
+bgmp 264/tcp
+bgmp 264/udp
+# 265-279 unassigned
+http-mgmt 280/tcp
+http-mgmt 280/udp
+personal-link 281/tcp
+personal-link 281/udp
+cableport-ax 282/tcp #cable port a/x
+cableport-ax 282/udp #cable port a/x
+# 283-307 unassigned
+novastorbakcup 308/tcp #novastor backup
+novastorbakcup 308/udp #novastor backup
+entrusttime 309/tcp
+entrusttime 309/udp
+bhmds 310/tcp
+bhmds 310/udp
+asip-webadmin 311/tcp #appleshare ip webadmin
+asip-webadmin 311/udp #appleshare ip webadmin
+vslmp 312/tcp
+vslmp 312/udp
+magenta-logic 313/tcp
+magenta-logic 313/udp
+opalis-robot 314/tcp
+opalis-robot 314/udp
+dpsi 315/tcp
+dpsi 315/udp
+decauth 316/tcp
+decauth 316/udp
+zannet 317/tcp
+zannet 317/udp
+# 318-320 #unassigned
+pip 321/tcp
+pip 321/udp
+# 322-343 #unassigned
+pdap 344/tcp #Prospero Data Access Protocol
+pdap 344/udp #Prospero Data Access Protocol
+pawserv 345/tcp #Perf Analysis Workbench
+pawserv 345/udp #Perf Analysis Workbench
+zserv 346/tcp #Zebra server
+zserv 346/udp #Zebra server
+fatserv 347/tcp #Fatmen Server
+fatserv 347/udp #Fatmen Server
+csi-sgwp 348/tcp #Cabletron Management Protocol
+csi-sgwp 348/udp #Cabletron Management Protocol
+mftp 349/tcp
+mftp 349/udp
+matip-type-a 350/tcp #MATIP Type A
+matip-type-a 350/udp
+matip-type-b 351/tcp #MATIP Type B
+matip-type-b 351/udp
+bhoetty 351/tcp #unassigned but widespread use
+bhoetty 351/udp #unassigned but widespread use
+dtag-ste-sb 352/tcp #DTAG
+dtag-ste-sb 352/udp #DTAG
+bhoedap4 352/tcp #unassigned but widespread use
+bhoedap4 352/udp #unassigned but widespread use
+ndsauth 353/tcp
+ndsauth 353/udp
+bh611 354/tcp
+bh611 354/udp
+datex-asn 355/tcp
+datex-asn 355/udp
+cloanto-net-1 356/tcp #Cloanto Net 1
+cloanto-net-1 356/udp
+bhevent 357/tcp
+bhevent 357/udp
+shrinkwrap 358/tcp
+shrinkwrap 358/udp
+tenebris_nts 359/tcp #Tenebris Network Trace Service
+tenebris_nts 359/udp #Tenebris Network Trace Service
+scoi2odialog 360/tcp
+scoi2odialog 360/udp
+semantix 361/tcp
+semantix 361/udp
+srssend 362/tcp #SRS Send
+srssend 362/udp #SRS Send
+rsvp_tunnel 363/tcp
+rsvp_tunnel 363/udp
+aurora-cmgr 364/tcp
+aurora-cmgr 364/udp
+dtk 365/tcp #Deception Tool Kit - Fred Cohen <fc@all.net>
+dtk 365/udp #Deception Tool Kit - Fred Cohen <fc@all.net>
+odmr 366/tcp
+odmr 366/udp
+mortgageware 367/tcp
+mortgageware 367/udp
+qbikgdp 368/tcp #QbikGDP
+qbikgdp 368/udp
+rpc2portmap 369/tcp
+rpc2portmap 369/udp
+codaauth2 370/tcp
+codaauth2 370/udp
+clearcase 371/tcp
+clearcase 371/udp
+ulistserv 372/tcp ulistproc #Unix Listserv
+ulistserv 372/udp ulistproc #Unix Listserv
+legent-1 373/tcp #Legent Corporation (now Computer Associates Intl.)
+legent-1 373/udp #Legent Corporation (now Computer Associates Intl.)
+legent-2 374/tcp #Legent Corporation (now Computer Associates Intl.)
+legent-2 374/udp #Legent Corporation (now Computer Associates Intl.)
+hassle 375/tcp
+hassle 375/udp
+nip 376/tcp #Amiga Envoy Network Inquiry Proto
+nip 376/udp #Amiga Envoy Network Inquiry Proto
+tnETOS 377/tcp #NEC Corporation
+tnETOS 377/udp #NEC Corporation
+dsETOS 378/tcp #NEC Corporation
+dsETOS 378/udp #NEC Corporation
+is99c 379/tcp #TIA/EIA/IS-99 modem client
+is99c 379/udp #TIA/EIA/IS-99 modem client
+is99s 380/tcp #TIA/EIA/IS-99 modem server
+is99s 380/udp #TIA/EIA/IS-99 modem server
+hp-collector 381/tcp #hp performance data collector
+hp-collector 381/udp #hp performance data collector
+hp-managed-node 382/tcp #hp performance data managed node
+hp-managed-node 382/udp #hp performance data managed node
+hp-alarm-mgr 383/tcp #hp performance data alarm manager
+hp-alarm-mgr 383/udp #hp performance data alarm manager
+arns 384/tcp #A Remote Network Server System
+arns 384/udp #A Remote Network Server System
+ibm-app 385/tcp #IBM Application
+ibm-app 385/udp #IBM Application
+asa 386/tcp #ASA Message Router Object Def.
+asa 386/udp #ASA Message Router Object Def.
+aurp 387/tcp #Appletalk Update-Based Routing Pro.
+aurp 387/udp #Appletalk Update-Based Routing Pro.
+unidata-ldm 388/tcp #Unidata LDM Version 4
+unidata-ldm 388/udp #Unidata LDM Version 4
+ldap 389/tcp #Lightweight Directory Access Protocol
+ldap 389/udp #Lightweight Directory Access Protocol
+uis 390/tcp
+uis 390/udp
+synotics-relay 391/tcp #SynOptics SNMP Relay Port
+synotics-relay 391/udp #SynOptics SNMP Relay Port
+synotics-broker 392/tcp #SynOptics Port Broker Port
+synotics-broker 392/udp #SynOptics Port Broker Port
+dis 393/tcp #Data Interpretation System
+dis 393/udp #Data Interpretation System
+embl-ndt 394/tcp #EMBL Nucleic Data Transfer
+embl-ndt 394/udp #EMBL Nucleic Data Transfer
+netcp 395/tcp #NETscout Control Protocol
+netcp 395/udp #NETscout Control Protocol
+netware-ip 396/tcp #Novell Netware over IP
+netware-ip 396/udp #Novell Netware over IP
+mptn 397/tcp #Multi Protocol Trans. Net.
+mptn 397/udp #Multi Protocol Trans. Net.
+kryptolan 398/tcp
+kryptolan 398/udp
+iso-tsap-c2 399/tcp #ISO-TSAP Class 2
+iso-tsap-c2 399/udp #ISO-TSAP Class 2
+work-sol 400/tcp #Workstation Solutions
+work-sol 400/udp #Workstation Solutions
+ups 401/tcp #Uninterruptible Power Supply
+ups 401/udp #Uninterruptible Power Supply
+genie 402/tcp #Genie Protocol
+genie 402/udp #Genie Protocol
+decap 403/tcp
+decap 403/udp
+nced 404/tcp
+nced 404/udp
+ncld 405/tcp
+ncld 405/udp
+imsp 406/tcp #Interactive Mail Support Protocol
+imsp 406/udp #Interactive Mail Support Protocol
+timbuktu 407/tcp
+timbuktu 407/udp
+prm-sm 408/tcp #Prospero Resource Manager Sys. Man.
+prm-sm 408/udp #Prospero Resource Manager Sys. Man.
+prm-nm 409/tcp #Prospero Resource Manager Node Man.
+prm-nm 409/udp #Prospero Resource Manager Node Man.
+decladebug 410/tcp #DECLadebug Remote Debug Protocol
+decladebug 410/udp #DECLadebug Remote Debug Protocol
+rmt 411/tcp #Remote MT Protocol
+rmt 411/udp #Remote MT Protocol
+synoptics-trap 412/tcp #Trap Convention Port
+synoptics-trap 412/udp #Trap Convention Port
+smsp 413/tcp
+smsp 413/udp
+infoseek 414/tcp
+infoseek 414/udp
+bnet 415/tcp
+bnet 415/udp
+silverplatter 416/tcp
+silverplatter 416/udp
+onmux 417/tcp
+onmux 417/udp
+hyper-g 418/tcp
+hyper-g 418/udp
+ariel1 419/tcp
+ariel1 419/udp
+smpte 420/tcp
+smpte 420/udp
+ariel2 421/tcp
+ariel2 421/udp
+ariel3 422/tcp
+ariel3 422/udp
+opc-job-start 423/tcp #IBM Operations Planning and Control Start
+opc-job-start 423/udp #IBM Operations Planning and Control Start
+opc-job-track 424/tcp #IBM Operations Planning and Control Track
+opc-job-track 424/udp #IBM Operations Planning and Control Track
+icad-el 425/tcp
+icad-el 425/udp
+smartsdp 426/tcp
+smartsdp 426/udp
+svrloc 427/tcp #Server Location
+svrloc 427/udp #Server Location
+ocs_cmu 428/tcp
+ocs_cmu 428/udp
+ocs_amu 429/tcp
+ocs_amu 429/udp
+utmpsd 430/tcp
+utmpsd 430/udp
+utmpcd 431/tcp
+utmpcd 431/udp
+iasd 432/tcp
+iasd 432/udp
+nnsp 433/tcp
+nnsp 433/udp
+mobileip-agent 434/tcp
+mobileip-agent 434/udp
+mobilip-mn 435/tcp
+mobilip-mn 435/udp
+dna-cml 436/tcp
+dna-cml 436/udp
+comscm 437/tcp
+comscm 437/udp
+dsfgw 438/tcp
+dsfgw 438/udp
+dasp 439/tcp
+dasp 439/udp
+sgcp 440/tcp
+sgcp 440/udp
+decvms-sysmgt 441/tcp
+decvms-sysmgt 441/udp
+cvc_hostd 442/tcp
+cvc_hostd 442/udp
+https 443/tcp
+https 443/udp
+snpp 444/tcp #Simple Network Paging Protocol
+snpp 444/udp #Simple Network Paging Protocol
+# [RFC1568]
+microsoft-ds 445/tcp
+microsoft-ds 445/udp
+ddm-rdb 446/tcp
+ddm-rdb 446/udp
+ddm-dfm 447/tcp
+ddm-dfm 447/udp
+ddm-ssl 448/tcp ddm-byte
+ddm-ssl 448/udp ddm-byte
+as-servermap 449/tcp #AS Server Mapper
+as-servermap 449/udp #AS Server Mapper
+tserver 450/tcp
+tserver 450/udp
+sfs-smp-net 451/tcp #Cray Network Semaphore server
+sfs-smp-net 451/udp #Cray Network Semaphore server
+sfs-config 452/tcp #Cray SFS config server
+sfs-config 452/udp #Cray SFS config server
+creativeserver 453/tcp #CreativeServer
+creativeserver 453/udp #CreativeServer
+contentserver 454/tcp #ContentServer
+contentserver 454/udp #ContentServer
+creativepartnr 455/tcp #CreativePartnr
+creativepartnr 455/udp #CreativePartnr
+macon-tcp 456/tcp
+macon-udp 456/udp
+scohelp 457/tcp
+scohelp 457/udp
+appleqtc 458/tcp #apple quick time
+appleqtc 458/udp #apple quick time
+ampr-rcmd 459/tcp
+ampr-rcmd 459/udp
+skronk 460/tcp
+skronk 460/udp
+datasurfsrv 461/tcp
+datasurfsrv 461/udp
+datasurfsrvsec 462/tcp
+datasurfsrvsec 462/udp
+alpes 463/tcp
+alpes 463/udp
+#
+kpasswd5 464/tcp # Kerberos (v5)
+kpasswd5 464/udp # Kerberos (v5)
+#PROBLEMS!==============================================================
+# IANA has offically assigned these two ports as ``kpasswd''
+#kpasswd 464/tcp # Kerberos (v5)
+#kpasswd 464/udp # Kerberos (v5)
+#PROBLEMS!==============================================================
+smtps 465/tcp #smtp protocol over TLS/SSL (was ssmtp)
+smtps 465/udp #smtp protocol over TLS/SSL (was ssmtp)
+digital-vrc 466/tcp
+digital-vrc 466/udp
+mylex-mapd 467/tcp
+mylex-mapd 467/udp
+photuris 468/tcp
+photuris 468/udp
+rcp 469/tcp #Radio Control Protocol
+rcp 469/udp #Radio Control Protocol
+scx-proxy 470/tcp
+scx-proxy 470/udp
+mondex 471/tcp
+mondex 471/udp
+ljk-login 472/tcp
+ljk-login 472/udp
+hybrid-pop 473/tcp
+hybrid-pop 473/udp
+tn-tl-w1 474/tcp
+tn-tl-w2 474/udp
+tcpnethaspsrv 475/tcp
+tcpnethaspsrv 475/udp
+tn-tl-fd1 476/tcp
+tn-tl-fd1 476/udp
+ss7ns 477/tcp
+ss7ns 477/udp
+spsc 478/tcp
+spsc 478/udp
+iafserver 479/tcp
+iafserver 479/udp
+iafdbase 480/tcp
+iafdbase 480/udp
+ph 481/tcp
+ph 481/udp
+bgs-nsi 482/tcp
+bgs-nsi 482/udp
+ulpnet 483/tcp
+ulpnet 483/udp
+integra-sme 484/tcp #Integra Software Management Environment
+integra-sme 484/udp #Integra Software Management Environment
+powerburst 485/tcp #Air Soft Power Burst
+powerburst 485/udp #Air Soft Power Burst
+avian 486/tcp
+avian 486/udp
+saft 487/tcp #saft Simple Asynchronous File Transfer
+saft 487/udp #saft Simple Asynchronous File Transfer
+gss-http 488/tcp
+gss-http 488/udp
+nest-protocol 489/tcp
+nest-protocol 489/udp
+micom-pfs 490/tcp
+micom-pfs 490/udp
+go-login 491/tcp
+go-login 491/udp
+ticf-1 492/tcp #Transport Independent Convergence for FNA
+ticf-1 492/udp #Transport Independent Convergence for FNA
+ticf-2 493/tcp #Transport Independent Convergence for FNA
+ticf-2 493/udp #Transport Independent Convergence for FNA
+pov-ray 494/tcp
+pov-ray 494/udp
+intecourier 495/tcp
+intecourier 495/udp
+pim-rp-disc 496/tcp
+pim-rp-disc 496/udp
+dantz 497/tcp
+dantz 497/udp
+siam 498/tcp
+siam 498/udp
+iso-ill 499/tcp #ISO ILL Protocol
+iso-ill 499/udp #ISO ILL Protocol
+isakmp 500/tcp
+isakmp 500/udp
+stmf 501/tcp
+stmf 501/udp
+asa-appl-proto 502/tcp
+asa-appl-proto 502/udp
+intrinsa 503/tcp
+intrinsa 503/udp
+citadel 504/tcp
+citadel 504/udp
+mailbox-lm 505/tcp
+mailbox-lm 505/udp
+ohimsrv 506/tcp
+ohimsrv 506/udp
+crs 507/tcp
+crs 507/udp
+xvttp 508/tcp
+xvttp 508/udp
+snare 509/tcp
+snare 509/udp
+fcp 510/tcp #FirstClass Protocol
+fcp 510/udp #FirstClass Protocol
+passgo 511/tcp
+passgo 511/udp
+#
+# Berkeley-specific services
+#
+exec 512/tcp #remote process execution;
+# authentication performed using
+# passwords and UNIX login names
+biff 512/udp comsat #used by mail system to notify users
+# of new mail received; currently
+# receives messages only from
+# processes on the same machine
+login 513/tcp #remote login a la telnet;
+# automatic authentication performed
+# based on priviledged port numbers
+# and distributed data bases which
+# identify "authentication domains"
+who 513/udp whod #maintains data bases showing who's
+# logged in to machines on a local
+# net and the load average of the
+# machine
+shell 514/tcp cmd #like exec, but automatic
+# authentication is performed as for
+# login server
+syslog 514/udp
+printer 515/tcp spooler
+printer 515/udp spooler
+videotex 516/tcp
+videotex 516/udp
+talk 517/tcp #like tenex link, but across
+# machine - unfortunately, doesn't
+# use link protocol (this is actually
+# just a rendezvous port from which a
+# tcp connection is established)
+talk 517/udp #like tenex link, but across
+# machine - unfortunately, doesn't
+# use link protocol (this is actually
+# just a rendezvous port from which a
+# tcp connection is established)
+ntalk 518/tcp
+ntalk 518/udp
+utime 519/tcp unixtime
+utime 519/udp unixtime
+efs 520/tcp #extended file name server
+router 520/udp route routed #local routing process (on site);
+# uses variant of Xerox NS routing
+# information protocol
+ripng 521/tcp
+ripng 521/udp
+ulp 522/tcp
+ulp 522/udp
+ibm-db2 523/tcp
+ibm-db2 523/udp
+ncp 524/tcp
+ncp 524/udp
+timed 525/tcp timeserver
+timed 525/udp timeserver
+tempo 526/tcp newdate
+tempo 526/udp newdate
+stx 527/tcp #Stock IXChange
+stx 527/udp #Stock IXChange
+custix 528/tcp #Customer IXChange
+custix 528/udp #Customer IXChange
+irc-serv 529/tcp
+irc-serv 529/udp
+courier 530/tcp rpc
+courier 530/udp rpc
+conference 531/tcp chat
+conference 531/udp chat
+netnews 532/tcp readnews
+netnews 532/udp readnews
+netwall 533/tcp #for emergency broadcasts
+netwall 533/udp #for emergency broadcasts
+mm-admin 534/tcp #MegaMedia Admin
+mm-admin 534/udp #MegaMedia Admin
+iiop 535/tcp
+iiop 535/udp
+opalis-rdv 536/tcp
+opalis-rdv 536/udp
+nmsp 537/tcp #Networked Media Streaming Protocol
+nmsp 537/udp #Networked Media Streaming Protocol
+gdomap 538/tcp
+gdomap 538/udp
+apertus-ldp 539/tcp #Apertus Technologies Load Determination
+apertus-ldp 539/udp #Apertus Technologies Load Determination
+uucp 540/tcp uucpd
+uucp 540/udp uucpd
+uucp-rlogin 541/tcp
+uucp-rlogin 541/udp
+commerce 542/tcp
+commerce 542/udp
+klogin 543/tcp # Kerberos (v4/v5)
+klogin 543/udp # Kerberos (v4/v5)
+kshell 544/tcp krcmd # Kerberos (v4/v5)
+kshell 544/udp krcmd # Kerberos (v4/v5)
+appleqtcsrvr 545/tcp
+appleqtcsrvr 545/udp
+dhcpv6-client 546/tcp #DHCPv6 Client
+dhcpv6-client 546/udp #DHCPv6 Client
+dhcpv6-server 547/tcp #DHCPv6 Server
+dhcpv6-server 547/udp #DHCPv6 Server
+afpovertcp 548/tcp #AFP over TCP
+afpovertcp 548/udp #AFP over TCP
+idfp 549/tcp
+idfp 549/udp
+new-rwho 550/tcp new-who
+new-rwho 550/udp new-who
+cybercash 551/tcp
+cybercash 551/udp
+deviceshare 552/tcp
+deviceshare 552/udp
+pirp 553/tcp
+pirp 553/udp
+rtsp 554/tcp #Real Time Stream Control Protocol
+rtsp 554/udp #Real Time Stream Control Protocol
+dsf 555/tcp
+dsf 555/udp
+remotefs 556/tcp rfs rfs_server # Brunhoff remote filesystem
+remotefs 556/udp rfs rfs_server # Brunhoff remote filesystem
+openvms-sysipc 557/tcp
+openvms-sysipc 557/udp
+sdnskmp 558/tcp
+sdnskmp 558/udp
+teedtap 559/tcp
+teedtap 559/udp
+rmonitor 560/tcp rmonitord
+rmonitor 560/udp rmonitord
+monitor 561/tcp
+monitor 561/udp
+chshell 562/tcp chcmd
+chshell 562/udp chcmd
+nntps 563/tcp snntp #nntp protocol over TLS/SSL
+nntps 563/udp snntp #nntp protocol over TLS/SSL
+9pfs 564/tcp #plan 9 file service
+9pfs 564/udp #plan 9 file service
+whoami 565/tcp
+whoami 565/udp
+streettalk 566/tcp
+banyan-rpc 567/tcp
+banyan-rpc 567/udp
+ms-shuttle 568/tcp #Microsoft shuttle
+ms-shuttle 568/udp #Microsoft shuttle
+ms-rome 569/tcp #Microsoft rome
+ms-rome 569/udp #Microsoft rome
+meter 570/tcp #demon
+meter 570/udp #demon
+umeter 571/tcp #udemon
+umeter 571/udp #udemon
+sonar 572/tcp
+sonar 572/udp
+banyan-vip 573/tcp
+banyan-vip 573/udp
+ftp-agent 574/tcp #FTP Software Agent System
+ftp-agent 574/udp #FTP Software Agent System
+vemmi 575/tcp
+vemmi 575/udp
+ipcd 576/tcp
+ipcd 576/udp
+vnas 577/tcp
+vnas 577/udp
+ipdd 578/tcp
+ipdd 578/udp
+decbsrv 579/tcp
+decbsrv 579/udp
+sntp-heartbeat 580/tcp
+sntp-heartbeat 580/udp
+bdp 581/tcp #Bundle Discovery Protocol
+bdp 581/udp #Bundle Discovery Protocol
+scc-security 582/tcp
+scc-security 582/udp
+philips-vc 583/tcp #Philips Video-Conferencing
+philips-vc 583/udp #Philips Video-Conferencing
+keyserver 584/tcp
+keyserver 584/udp
+#imap4-ssl@585 never should have been allocated. See PR 46294.
+#imap4-ssl 585/tcp #IMAP4+SSL (use of 585 is not recommended,
+#imap4-ssl 585/udp # use 993 instead)
+password-chg 586/tcp
+password-chg 586/udp
+submission 587/tcp
+submission 587/udp
+cal 588/tcp
+cal 588/udp
+eyelink 589/tcp
+eyelink 589/udp
+tns-cml 590/tcp
+tns-cml 590/udp
+http-alt 591/tcp #FileMaker, Inc. - HTTP Alternate (see Port 80)
+http-alt 591/udp #FileMaker, Inc. - HTTP Alternate (see Port 80)
+eudora-set 592/tcp
+eudora-set 592/udp
+http-rpc-epmap 593/tcp #HTTP RPC Ep Map
+http-rpc-epmap 593/udp #HTTP RPC Ep Map
+tpip 594/tcp
+tpip 594/udp
+cab-protocol 595/tcp
+cab-protocol 595/udp
+smsd 596/tcp
+smsd 596/udp
+ptcnameservice 597/tcp #PTC Name Service
+ptcnameservice 597/udp #PTC Name Service
+sco-websrvrmg3 598/tcp #SCO Web Server Manager 3
+sco-websrvrmg3 598/udp #SCO Web Server Manager 3
+acp 599/tcp #Aeolon Core Protocol
+acp 599/udp #Aeolon Core Protocol
+ipcserver 600/tcp #Sun IPC server
+ipcserver 600/udp #Sun IPC server
+nqs 607/tcp
+nqs 607/udp
+urm 606/tcp #Cray Unified Resource Manager
+urm 606/udp #Cray Unified Resource Manager
+sift-uft 608/tcp #Sender-Initiated/Unsolicited File Transfer
+sift-uft 608/udp #Sender-Initiated/Unsolicited File Transfer
+npmp-trap 609/tcp
+npmp-trap 609/udp
+npmp-local 610/tcp
+npmp-local 610/udp
+npmp-gui 611/tcp
+npmp-gui 611/udp
+sshell 614/tcp #SSLshell
+sshell 614/udp
+ipp 631/tcp #IPP (Internet Printing Protocol)
+ipp 631/udp #IPP (Internet Printing Protocol)
+ginad 634/tcp
+ginad 634/udp
+ldaps 636/tcp sldap #ldap protocol over TLS/SSL
+ldaps 636/udp sldap
+mdqs 666/tcp
+mdqs 666/udp
+#PROBLEMS!===============================================
+doom 666/tcp #doom Id Software
+doom 666/udp #doom Id Software
+#PROBLEMS!===============================================
+acap 674/tcp #Application Configuration Access Protocol
+acap 674/udp #Application Configuration Access Protocol
+elcsd 704/tcp #errlog copy/server daemon
+elcsd 704/udp #errlog copy/server daemon
+entrustmanager 709/tcp #EntrustManager
+entrustmanager 709/udp #EntrustManager
+netviewdm1 729/tcp #IBM NetView DM/6000 Server/Client
+netviewdm1 729/udp #IBM NetView DM/6000 Server/Client
+netviewdm2 730/tcp #IBM NetView DM/6000 send/tcp
+netviewdm2 730/udp #IBM NetView DM/6000 send/tcp
+netviewdm3 731/tcp #IBM NetView DM/6000 receive/tcp
+netviewdm3 731/udp #IBM NetView DM/6000 receive/tcp
+netgw 741/tcp
+netgw 741/udp
+netrcs 742/tcp #Network based Rev. Cont. Sys.
+netrcs 742/udp #Network based Rev. Cont. Sys.
+flexlm 744/tcp #Flexible License Manager
+flexlm 744/udp #Flexible License Manager
+fujitsu-dev 747/tcp #Fujitsu Device Control
+fujitsu-dev 747/udp #Fujitsu Device Control
+ris-cm 748/tcp #Russell Info Sci Calendar Manager
+ris-cm 748/udp #Russell Info Sci Calendar Manager
+kerberos-adm 749/tcp #Kerberos administration (v5)
+kerberos-adm 749/udp #Kerberos administration (v5)
+kerberos-iv 750/udp kdc # Kerberos (v4)
+kerberos-iv 750/tcp kdc # Kerberos (v4)
+#PROBLEMS!========================================================
+#rfile 750/tcp
+#loadav 750/udp
+#PROBLEMS!========================================================
+kerberos_master 751/tcp # Kerberos `kadmin' (v4)
+kerberos_master 751/udp # Kerberos `kadmin' (v4)
+#PROBLEMS!========================================================
+pump 751/tcp
+pump 751/udp
+#PROBLEMS!========================================================
+qrh 752/tcp
+qrh 752/udp
+rrh 753/tcp
+rrh 753/udp
+krb_prop 754/tcp krb5_prop # kerberos/v5 server propagation
+#PROBLEMS!========================================================
+tell 754/tcp #send
+#PROBLEMS!========================================================
+tell 754/udp #send
+nlogin 758/tcp
+nlogin 758/udp
+con 759/tcp
+con 759/udp
+krbupdate 760/tcp kreg # Kerberos (v4) registration
+#PROBLEMS!========================================================
+ns 760/tcp
+#PROBLEMS!========================================================
+ns 760/udp
+kpasswd 761/tcp kpwd # Kerberos (v4) "passwd"
+#PROBLEMS!========================================================
+rxe 761/tcp
+#PROBLEMS!========================================================
+rxe 761/udp
+quotad 762/tcp
+quotad 762/udp
+cycleserv 763/tcp
+cycleserv 763/udp
+omserv 764/tcp
+omserv 764/udp
+webster 765/tcp
+webster 765/udp
+phonebook 767/tcp #phone
+phonebook 767/udp #phone
+vid 769/tcp
+vid 769/udp
+cadlock 770/tcp
+cadlock 770/udp
+rtip 771/tcp
+rtip 771/udp
+cycleserv2 772/tcp
+cycleserv2 772/udp
+submit 773/tcp
+notify 773/udp
+rpasswd 774/tcp
+acmaint_dbd 774/udp
+entomb 775/tcp
+acmaint_transd 775/udp
+wpages 776/tcp
+wpages 776/udp
+wpgs 780/tcp
+wpgs 780/udp
+concert 786/tcp
+concert 786/udp
+mdbs_daemon 800/tcp
+mdbs_daemon 800/udp
+device 801/tcp
+device 801/udp
+supfilesrv 871/tcp # for SUP
+rsync 873/tcp
+rsync 873/udp
+accessbuilder 888/tcp
+accessbuilder 888/udp
+swat 901/tcp # samba web configuration tool
+ftps-data 989/tcp # ftp protocol, data, over TLS/SSL
+ftps-data 989/udp
+ftps 990/tcp # ftp protocol, control, over TLS/SSL
+ftps 990/udp
+telnets 992/tcp # telnet protocol over TLS/SSL
+telnets 992/udp
+imaps 993/tcp # imap4 protocol over TLS/SSL
+imaps 993/udp
+ircs 994/tcp # irc protocol over TLS/SSL
+ircs 994/udp
+pop3s 995/tcp spop3 # pop3 protocol over TLS/SSL
+pop3s 995/udp spop3
+vsinet 996/tcp
+vsinet 996/udp
+maitrd 997/tcp
+maitrd 997/udp
+busboy 998/tcp
+puparp 998/udp
+garcon 999/tcp
+applix 999/udp #Applix ac
+puprouter 999/tcp
+puprouter 999/udp
+cadlock 1000/tcp
+ock 1000/udp
+#
+# REGISTERED PORT NUMBERS
+#
+blackjack 1025/tcp #network blackjack
+blackjack 1025/udp #network blackjack
+iad1 1030/tcp #BBN IAD
+iad1 1030/udp #BBN IAD
+iad2 1031/tcp #BBN IAD
+iad2 1031/udp #BBN IAD
+iad3 1032/tcp #BBN IAD
+iad3 1032/udp #BBN IAD
+nim 1058/tcp
+nim 1058/udp
+nimreg 1059/tcp
+nimreg 1059/udp
+instl_boots 1067/tcp #Installation Bootstrap Proto. Serv.
+instl_boots 1067/udp #Installation Bootstrap Proto. Serv.
+instl_bootc 1068/tcp #Installation Bootstrap Proto. Cli.
+instl_bootc 1068/udp #Installation Bootstrap Proto. Cli.
+socks 1080/tcp
+socks 1080/udp
+ansoft-lm-1 1083/tcp #Anasoft License Manager
+ansoft-lm-1 1083/udp #Anasoft License Manager
+ansoft-lm-2 1084/tcp #Anasoft License Manager
+ansoft-lm-2 1084/udp #Anasoft License Manager
+webobjects 1085/tcp #Web Objects
+webobjects 1085/udp #Web Objects
+kpop 1109/tcp #Unofficial
+kpop 1109/udp #Unofficial
+nfsd-status 1110/tcp #Cluster status info
+nfsd-keepalive 1110/udp #Client status info
+supfiledbg 1127/tcp # for SUP
+nfa 1155/tcp #Network File Access
+nfa 1155/udp #Network File Access
+phone 1167/udp #conference calling
+skkserv 1178/tcp #SKK (kanji input)
+lupa 1212/tcp
+lupa 1212/udp
+nerv 1222/tcp #SNI R&D network
+nerv 1222/udp #SNI R&D network
+hermes 1248/tcp
+hermes 1248/udp
+healthd 1281/tcp #healthd
+healthd 1281/udp #healthd
+alta-ana-lm 1346/tcp #Alta Analytics License Manager
+alta-ana-lm 1346/udp #Alta Analytics License Manager
+bbn-mmc 1347/tcp #multi media conferencing
+bbn-mmc 1347/udp #multi media conferencing
+bbn-mmx 1348/tcp #multi media conferencing
+bbn-mmx 1348/udp #multi media conferencing
+sbook 1349/tcp #Registration Network Protocol
+sbook 1349/udp #Registration Network Protocol
+editbench 1350/tcp #Registration Network Protocol
+editbench 1350/udp #Registration Network Protocol
+equationbuilder 1351/tcp #Digital Tool Works (MIT)
+equationbuilder 1351/udp #Digital Tool Works (MIT)
+lotusnote 1352/tcp #Lotus Note
+lotusnote 1352/udp #Lotus Note
+relief 1353/tcp #Relief Consulting
+relief 1353/udp #Relief Consulting
+rightbrain 1354/tcp #RightBrain Software
+rightbrain 1354/udp #RightBrain Software
+intuitive-edge 1355/tcp #Intuitive Edge
+intuitive-edge 1355/udp #Intuitive Edge
+cuillamartin 1356/tcp #CuillaMartin Company
+cuillamartin 1356/udp #CuillaMartin Company
+pegboard 1357/tcp #Electronic PegBoard
+pegboard 1357/udp #Electronic PegBoard
+connlcli 1358/tcp
+connlcli 1358/udp
+ftsrv 1359/tcp
+ftsrv 1359/udp
+mimer 1360/tcp
+mimer 1360/udp
+linx 1361/tcp
+linx 1361/udp
+timeflies 1362/tcp
+timeflies 1362/udp
+ndm-requester 1363/tcp #Network DataMover Requester
+ndm-requester 1363/udp #Network DataMover Requester
+ndm-server 1364/tcp #Network DataMover Server
+ndm-server 1364/udp #Network DataMover Server
+adapt-sna 1365/tcp #Network Software Associates
+adapt-sna 1365/udp #Network Software Associates
+netware-csp 1366/tcp #Novell NetWare Comm Service Platform
+netware-csp 1366/udp #Novell NetWare Comm Service Platform
+dcs 1367/tcp
+dcs 1367/udp
+screencast 1368/tcp
+screencast 1368/udp
+gv-us 1369/tcp #GlobalView to Unix Shell
+gv-us 1369/udp #GlobalView to Unix Shell
+us-gv 1370/tcp #Unix Shell to GlobalView
+us-gv 1370/udp #Unix Shell to GlobalView
+fc-cli 1371/tcp #Fujitsu Config Protocol
+fc-cli 1371/udp #Fujitsu Config Protocol
+fc-ser 1372/tcp #Fujitsu Config Protocol
+fc-ser 1372/udp #Fujitsu Config Protocol
+chromagrafx 1373/tcp
+chromagrafx 1373/udp
+molly 1374/tcp #EPI Software Systems
+molly 1374/udp #EPI Software Systems
+bytex 1375/tcp
+bytex 1375/udp
+ibm-pps 1376/tcp #IBM Person to Person Software
+ibm-pps 1376/udp #IBM Person to Person Software
+cichlid 1377/tcp #Cichlid License Manager
+cichlid 1377/udp #Cichlid License Manager
+elan 1378/tcp #Elan License Manager
+elan 1378/udp #Elan License Manager
+dbreporter 1379/tcp #Integrity Solutions
+dbreporter 1379/udp #Integrity Solutions
+telesis-licman 1380/tcp #Telesis Network License Manager
+telesis-licman 1380/udp #Telesis Network License Manager
+apple-licman 1381/tcp #Apple Network License Manager
+apple-licman 1381/udp #Apple Network License Manager
+#udt_os 1382/tcp
+#udt_os 1382/udp
+gwha 1383/tcp #GW Hannaway Network License Manager
+gwha 1383/udp #GW Hannaway Network License Manager
+os-licman 1384/tcp #Objective Solutions License Manager
+os-licman 1384/udp #Objective Solutions License Manager
+atex_elmd 1385/tcp #Atex Publishing License Manager
+atex_elmd 1385/udp #Atex Publishing License Manager
+checksum 1386/tcp #CheckSum License Manager
+checksum 1386/udp #CheckSum License Manager
+cadsi-lm 1387/tcp #Computer Aided Design Software Inc LM
+cadsi-lm 1387/udp #Computer Aided Design Software Inc LM
+objective-dbc 1388/tcp #Objective Solutions DataBase Cache
+objective-dbc 1388/udp #Objective Solutions DataBase Cache
+iclpv-dm 1389/tcp #Document Manager
+iclpv-dm 1389/udp #Document Manager
+iclpv-sc 1390/tcp #Storage Controller
+iclpv-sc 1390/udp #Storage Controller
+iclpv-sas 1391/tcp #Storage Access Server
+iclpv-sas 1391/udp #Storage Access Server
+iclpv-pm 1392/tcp #Print Manager
+iclpv-pm 1392/udp #Print Manager
+iclpv-nls 1393/tcp #Network Log Server
+iclpv-nls 1393/udp #Network Log Server
+iclpv-nlc 1394/tcp #Network Log Client
+iclpv-nlc 1394/udp #Network Log Client
+iclpv-wsm 1395/tcp #PC Workstation Manager software
+iclpv-wsm 1395/udp #PC Workstation Manager software
+dvl-activemail 1396/tcp #DVL Active Mail
+dvl-activemail 1396/udp #DVL Active Mail
+audio-activmail 1397/tcp #Audio Active Mail
+audio-activmail 1397/udp #Audio Active Mail
+video-activmail 1398/tcp #Video Active Mail
+video-activmail 1398/udp #Video Active Mail
+cadkey-licman 1399/tcp #Cadkey License Manager
+cadkey-licman 1399/udp #Cadkey License Manager
+cadkey-tablet 1400/tcp #Cadkey Tablet Daemon
+cadkey-tablet 1400/udp #Cadkey Tablet Daemon
+goldleaf-licman 1401/tcp #Goldleaf License Manager
+goldleaf-licman 1401/udp #Goldleaf License Manager
+prm-sm-np 1402/tcp #Prospero Resource Manager
+prm-sm-np 1402/udp #Prospero Resource Manager
+prm-nm-np 1403/tcp #Prospero Resource Manager
+prm-nm-np 1403/udp #Prospero Resource Manager
+igi-lm 1404/tcp #Infinite Graphics License Manager
+igi-lm 1404/udp #Infinite Graphics License Manager
+ibm-res 1405/tcp #IBM Remote Execution Starter
+ibm-res 1405/udp #IBM Remote Execution Starter
+netlabs-lm 1406/tcp #NetLabs License Manager
+netlabs-lm 1406/udp #NetLabs License Manager
+dbsa-lm 1407/tcp #DBSA License Manager
+dbsa-lm 1407/udp #DBSA License Manager
+sophia-lm 1408/tcp #Sophia License Manager
+sophia-lm 1408/udp #Sophia License Manager
+here-lm 1409/tcp #Here License Manager
+here-lm 1409/udp #Here License Manager
+hiq 1410/tcp #HiQ License Manager
+hiq 1410/udp #HiQ License Manager
+af 1411/tcp #AudioFile
+af 1411/udp #AudioFile
+innosys 1412/tcp
+innosys 1412/udp
+innosys-acl 1413/tcp
+innosys-acl 1413/udp
+ibm-mqseries 1414/tcp #IBM MQSeries
+ibm-mqseries 1414/udp #IBM MQSeries
+dbstar 1415/tcp
+dbstar 1415/udp
+novell-lu6.2 1416/tcp #Novell LU6.2
+novell-lu6.2 1416/udp #Novell LU6.2
+timbuktu-srv1 1417/tcp #Timbuktu Service 1 Port
+timbuktu-srv1 1417/udp #Timbuktu Service 1 Port
+timbuktu-srv2 1418/tcp #Timbuktu Service 2 Port
+timbuktu-srv2 1418/udp #Timbuktu Service 2 Port
+timbuktu-srv3 1419/tcp #Timbuktu Service 3 Port
+timbuktu-srv3 1419/udp #Timbuktu Service 3 Port
+timbuktu-srv4 1420/tcp #Timbuktu Service 4 Port
+timbuktu-srv4 1420/udp #Timbuktu Service 4 Port
+gandalf-lm 1421/tcp #Gandalf License Manager
+gandalf-lm 1421/udp #Gandalf License Manager
+autodesk-lm 1422/tcp #Autodesk License Manager
+autodesk-lm 1422/udp #Autodesk License Manager
+essbase 1423/tcp #Essbase Arbor Software
+essbase 1423/udp #Essbase Arbor Software
+hybrid 1424/tcp #Hybrid Encryption Protocol
+hybrid 1424/udp #Hybrid Encryption Protocol
+zion-lm 1425/tcp #Zion Software License Manager
+zion-lm 1425/udp #Zion Software License Manager
+sas-1 1426/tcp #Satellite-data Acquisition System 1
+sas-1 1426/udp #Satellite-data Acquisition System 1
+mloadd 1427/tcp #mloadd monitoring tool
+mloadd 1427/udp #mloadd monitoring tool
+informatik-lm 1428/tcp #Informatik License Manager
+informatik-lm 1428/udp #Informatik License Manager
+nms 1429/tcp #Hypercom NMS
+nms 1429/udp #Hypercom NMS
+tpdu 1430/tcp #Hypercom TPDU
+tpdu 1430/udp #Hypercom TPDU
+rgtp 1431/tcp #Reverse Gossip Transport
+rgtp 1431/udp #Reverse Gossip Transport
+blueberry-lm 1432/tcp #Blueberry Software License Manager
+blueberry-lm 1432/udp #Blueberry Software License Manager
+ms-sql-s 1433/tcp #Microsoft-SQL-Server
+ms-sql-s 1433/udp #Microsoft-SQL-Server
+ms-sql-m 1434/tcp #Microsoft-SQL-Monitor
+ms-sql-m 1434/udp #Microsoft-SQL-Monitor
+ibm-cics 1435/tcp
+ibm-cics 1435/udp
+sas-2 1436/tcp #Satellite-data Acquisition System 2
+sas-2 1436/udp #Satellite-data Acquisition System 2
+tabula 1437/tcp
+tabula 1437/udp
+eicon-server 1438/tcp #Eicon Security Agent/Server
+eicon-server 1438/udp #Eicon Security Agent/Server
+eicon-x25 1439/tcp #Eicon X25/SNA Gateway
+eicon-x25 1439/udp #Eicon X25/SNA Gateway
+eicon-slp 1440/tcp #Eicon Service Location Protocol
+eicon-slp 1440/udp #Eicon Service Location Protocol
+cadis-1 1441/tcp #Cadis License Management
+cadis-1 1441/udp #Cadis License Management
+cadis-2 1442/tcp #Cadis License Management
+cadis-2 1442/udp #Cadis License Management
+ies-lm 1443/tcp #Integrated Engineering Software
+ies-lm 1443/udp #Integrated Engineering Software
+marcam-lm 1444/tcp #Marcam License Management
+marcam-lm 1444/udp #Marcam License Management
+proxima-lm 1445/tcp #Proxima License Manager
+proxima-lm 1445/udp #Proxima License Manager
+ora-lm 1446/tcp #Optical Research Associates License Manager
+ora-lm 1446/udp #Optical Research Associates License Manager
+apri-lm 1447/tcp #Applied Parallel Research LM
+apri-lm 1447/udp #Applied Parallel Research LM
+oc-lm 1448/tcp #OpenConnect License Manager
+oc-lm 1448/udp #OpenConnect License Manager
+peport 1449/tcp
+peport 1449/udp
+dwf 1450/tcp #Tandem Distributed Workbench Facility
+dwf 1450/udp #Tandem Distributed Workbench Facility
+infoman 1451/tcp #IBM Information Management
+infoman 1451/udp #IBM Information Management
+gtegsc-lm 1452/tcp #GTE Government Systems License Man
+gtegsc-lm 1452/udp #GTE Government Systems License Man
+genie-lm 1453/tcp #Genie License Manager
+genie-lm 1453/udp #Genie License Manager
+interhdl_elmd 1454/tcp #interHDL License Manager
+interhdl_elmd 1454/udp #interHDL License Manager
+esl-lm 1455/tcp #ESL License Manager
+esl-lm 1455/udp #ESL License Manager
+dca 1456/tcp
+dca 1456/udp
+valisys-lm 1457/tcp #Valisys License Manager
+valisys-lm 1457/udp #Valisys License Manager
+nrcabq-lm 1458/tcp #Nichols Research Corp.
+nrcabq-lm 1458/udp #Nichols Research Corp.
+proshare1 1459/tcp #Proshare Notebook Application
+proshare1 1459/udp #Proshare Notebook Application
+proshare2 1460/tcp #Proshare Notebook Application
+proshare2 1460/udp #Proshare Notebook Application
+ibm_wrless_lan 1461/tcp #IBM Wireless LAN
+ibm_wrless_lan 1461/udp #IBM Wireless LAN
+world-lm 1462/tcp #World License Manager
+world-lm 1462/udp #World License Manager
+nucleus 1463/tcp
+nucleus 1463/udp
+msl_lmd 1464/tcp #MSL License Manager
+msl_lmd 1464/udp #MSL License Manager
+pipes 1465/tcp #Pipes Platform
+pipes 1465/udp #Pipes Platform mfarlin@peerlogic.com
+oceansoft-lm 1466/tcp #Ocean Software License Manager
+oceansoft-lm 1466/udp #Ocean Software License Manager
+csdmbase 1467/tcp
+csdmbase 1467/udp
+csdm 1468/tcp
+csdm 1468/udp
+aal-lm 1469/tcp #Active Analysis Limited License Manager
+aal-lm 1469/udp #Active Analysis Limited License Manager
+uaiact 1470/tcp #Universal Analytics
+uaiact 1470/udp #Universal Analytics
+csdmbase 1471/tcp
+csdmbase 1471/udp
+csdm 1472/tcp
+csdm 1472/udp
+openmath 1473/tcp
+openmath 1473/udp
+telefinder 1474/tcp
+telefinder 1474/udp
+taligent-lm 1475/tcp #Taligent License Manager
+taligent-lm 1475/udp #Taligent License Manager
+clvm-cfg 1476/tcp
+clvm-cfg 1476/udp
+ms-sna-server 1477/tcp
+ms-sna-server 1477/udp
+ms-sna-base 1478/tcp
+ms-sna-base 1478/udp
+dberegister 1479/tcp
+dberegister 1479/udp
+pacerforum 1480/tcp
+pacerforum 1480/udp
+airs 1481/tcp
+airs 1481/udp
+miteksys-lm 1482/tcp #Miteksys License Manager
+miteksys-lm 1482/udp #Miteksys License Manager
+afs 1483/tcp #AFS License Manager
+afs 1483/udp #AFS License Manager
+confluent 1484/tcp #Confluent License Manager
+confluent 1484/udp #Confluent License Manager
+lansource 1485/tcp
+lansource 1485/udp
+nms_topo_serv 1486/tcp
+nms_topo_serv 1486/udp
+localinfosrvr 1487/tcp
+localinfosrvr 1487/udp
+docstor 1488/tcp
+docstor 1488/udp
+dmdocbroker 1489/tcp
+dmdocbroker 1489/udp
+insitu-conf 1490/tcp
+insitu-conf 1490/udp
+anynetgateway 1491/tcp
+anynetgateway 1491/udp
+stone-design-1 1492/tcp
+stone-design-1 1492/udp
+netmap_lm 1493/tcp
+netmap_lm 1493/udp
+ica 1494/tcp
+ica 1494/udp
+cvc 1495/tcp
+cvc 1495/udp
+liberty-lm 1496/tcp
+liberty-lm 1496/udp
+rfx-lm 1497/tcp
+rfx-lm 1497/udp
+watcom-sql 1498/tcp
+watcom-sql 1498/udp
+fhc 1499/tcp #Federico Heinz Consultora
+fhc 1499/udp #Federico Heinz Consultora
+vlsi-lm 1500/tcp #VLSI License Manager
+vlsi-lm 1500/udp #VLSI License Manager
+sas-3 1501/tcp #Satellite-data Acquisition System 3
+sas-3 1501/udp #Satellite-data Acquisition System 3
+shivadiscovery 1502/tcp #Shiva
+shivadiscovery 1502/udp #Shiva
+imtc-mcs 1503/tcp #Databeam
+imtc-mcs 1503/udp #Databeam
+evb-elm 1504/tcp #EVB Software Engineering License Manager
+evb-elm 1504/udp #EVB Software Engineering License Manager
+funkproxy 1505/tcp #Funk Software, Inc.
+funkproxy 1505/udp #Funk Software, Inc.
+utcd 1506/tcp #Universal Time daemon (utcd)
+utcd 1506/udp #Universal Time daemon (utcd)
+symplex 1507/tcp
+symplex 1507/udp
+diagmond 1508/tcp
+diagmond 1508/udp
+robcad-lm 1509/tcp #Robcad, Ltd. License Manager
+robcad-lm 1509/udp #Robcad, Ltd. License Manager
+mvx-lm 1510/tcp #Midland Valley Exploration Ltd. Lic. Man.
+mvx-lm 1510/udp #Midland Valley Exploration Ltd. Lic. Man.
+3l-l1 1511/tcp
+3l-l1 1511/udp
+wins 1512/tcp #Microsoft's Windows Internet Name Service
+wins 1512/udp #Microsoft's Windows Internet Name Service
+fujitsu-dtc 1513/tcp #Fujitsu Systems Business of America, Inc
+fujitsu-dtc 1513/udp #Fujitsu Systems Business of America, Inc
+fujitsu-dtcns 1514/tcp #Fujitsu Systems Business of America, Inc
+fujitsu-dtcns 1514/udp #Fujitsu Systems Business of America, Inc
+ifor-protocol 1515/tcp
+ifor-protocol 1515/udp
+vpad 1516/tcp #Virtual Places Audio data
+vpad 1516/udp #Virtual Places Audio data
+vpac 1517/tcp #Virtual Places Audio control
+vpac 1517/udp #Virtual Places Audio control
+vpvd 1518/tcp #Virtual Places Video data
+vpvd 1518/udp #Virtual Places Video data
+vpvc 1519/tcp #Virtual Places Video control
+vpvc 1519/udp #Virtual Places Video control
+atm-zip-office 1520/tcp #atm zip office
+atm-zip-office 1520/udp #atm zip office
+ncube-lm 1521/tcp #nCube License Manager
+ncube-lm 1521/udp #nCube License Manager
+rna-lm 1522/tcp #Ricardo North America License Manager
+rna-lm 1522/udp #Ricardo North America License Manager
+cichild-lm 1523/tcp
+cichild-lm 1523/udp
+ingreslock 1524/tcp #ingres
+ingreslock 1524/udp #ingres
+prospero-np 1525/tcp #Prospero Directory Service non-priv
+prospero-np 1525/udp #Prospero Directory Service non-priv
+#PROBLEMS!========================================================
+orasrv 1525/tcp #oracle
+orasrv 1525/udp #oracle
+#PROBLEMS!========================================================
+pdap-np 1526/tcp #Prospero Data Access Prot non-priv
+pdap-np 1526/udp #Prospero Data Access Prot non-priv
+tlisrv 1527/tcp #oracle
+tlisrv 1527/udp #oracle
+mciautoreg 1528/tcp
+mciautoreg 1528/udp
+support 1529/tcp prmsd gnatsd # cygnus bug tracker
+coauthor 1529/tcp #oracle
+coauthor 1529/udp #oracle
+rap-service 1530/tcp
+rap-service 1530/udp
+rap-listen 1531/tcp
+rap-listen 1531/udp
+miroconnect 1532/tcp
+miroconnect 1532/udp
+virtual-places 1533/tcp #Virtual Places Software
+virtual-places 1533/udp #Virtual Places Software
+micromuse-lm 1534/tcp
+micromuse-lm 1534/udp
+ampr-info 1535/tcp
+ampr-info 1535/udp
+ampr-inter 1536/tcp
+ampr-inter 1536/udp
+sdsc-lm 1537/tcp
+sdsc-lm 1537/udp
+3ds-lm 1538/tcp
+3ds-lm 1538/udp
+intellistor-lm 1539/tcp #Intellistor License Manager
+intellistor-lm 1539/udp #Intellistor License Manager
+rds 1540/tcp
+rds 1540/udp
+rds2 1541/tcp
+rds2 1541/udp
+gridgen-elmd 1542/tcp
+gridgen-elmd 1542/udp
+simba-cs 1543/tcp
+simba-cs 1543/udp
+aspeclmd 1544/tcp
+aspeclmd 1544/udp
+vistium-share 1545/tcp
+vistium-share 1545/udp
+abbaccuray 1546/tcp
+abbaccuray 1546/udp
+laplink 1547/tcp
+laplink 1547/udp
+axon-lm 1548/tcp #Axon License Manager
+axon-lm 1548/udp #Axon License Manager
+shivahose 1549/tcp #Shiva Hose
+shivasound 1549/udp #Shiva Sound
+3m-image-lm 1550/tcp #Image Storage license manager 3M Company
+3m-image-lm 1550/udp #Image Storage license manager 3M Company
+hecmtl-db 1551/tcp
+hecmtl-db 1551/udp
+pciarray 1552/tcp
+pciarray 1552/udp
+issd 1600/tcp
+issd 1600/udp
+# IMPORTANT NOTE: Ports 1645/1646 are the traditional radius ports used by
+# many vendors without obtaining official IANA assignment. The official
+# assignment is now ports 1812/1813 and users are encouraged to migrate
+# when possible to these new ports.
+#radius 1645/udp #RADIUS authentication protocol (old)
+#radacct 1646/udp #RADIUS accounting protocol (old)
+nkd 1650/tcp
+nkd 1650/udp
+shiva_confsrvr 1651/tcp
+shiva_confsrvr 1651/udp
+xnmp 1652/tcp
+xnmp 1652/udp
+netview-aix-1 1661/tcp
+netview-aix-1 1661/udp
+netview-aix-2 1662/tcp
+netview-aix-2 1662/udp
+netview-aix-3 1663/tcp
+netview-aix-3 1663/udp
+netview-aix-4 1664/tcp
+netview-aix-4 1664/udp
+netview-aix-5 1665/tcp
+netview-aix-5 1665/udp
+netview-aix-6 1666/tcp
+netview-aix-6 1666/udp
+netview-aix-7 1667/tcp
+netview-aix-7 1667/udp
+netview-aix-8 1668/tcp
+netview-aix-8 1668/udp
+netview-aix-9 1669/tcp
+netview-aix-9 1669/udp
+netview-aix-10 1670/tcp
+netview-aix-10 1670/udp
+netview-aix-11 1671/tcp
+netview-aix-11 1671/udp
+netview-aix-12 1672/tcp
+netview-aix-12 1672/udp
+l2f 1701/tcp #l2f
+l2f 1701/udp #l2f
+l2tp 1701/tcp #Layer 2 Tunnelling Protocol
+l2tp 1701/udp #Layer 2 Tunnelling Protocol
+pptp 1723/tcp #Point-to-point tunnelling protocol
+# IMPORTANT NOTE: See comments for ports 1645/1646 when using older equipment
+radius 1812/udp #RADIUS authentication protocol (IANA sanctioned)
+radacct 1813/udp #RADIUS accounting protocol (IANA sanctioned)
+licensedaemon 1986/tcp #cisco license management
+licensedaemon 1986/udp #cisco license management
+tr-rsrb-p1 1987/tcp #cisco RSRB Priority 1 port
+tr-rsrb-p1 1987/udp #cisco RSRB Priority 1 port
+tr-rsrb-p2 1988/tcp #cisco RSRB Priority 2 port
+tr-rsrb-p2 1988/udp #cisco RSRB Priority 2 port
+tr-rsrb-p3 1989/tcp #cisco RSRB Priority 3 port
+tr-rsrb-p3 1989/udp #cisco RSRB Priority 3 port
+#PROBLEMS!===================================================
+mshnet 1989/tcp #MHSnet system
+mshnet 1989/udp #MHSnet system
+#PROBLEMS!===================================================
+stun-p1 1990/tcp #cisco STUN Priority 1 port
+stun-p1 1990/udp #cisco STUN Priority 1 port
+stun-p2 1991/tcp #cisco STUN Priority 2 port
+stun-p2 1991/udp #cisco STUN Priority 2 port
+stun-p3 1992/tcp #cisco STUN Priority 3 port
+stun-p3 1992/udp #cisco STUN Priority 3 port
+#PROBLEMS!===================================================
+ipsendmsg 1992/tcp
+ipsendmsg 1992/udp
+#PROBLEMS!===================================================
+snmp-tcp-port 1993/tcp #cisco SNMP TCP port
+snmp-tcp-port 1993/udp #cisco SNMP TCP port
+stun-port 1994/tcp #cisco serial tunnel port
+stun-port 1994/udp #cisco serial tunnel port
+perf-port 1995/tcp #cisco perf port
+perf-port 1995/udp #cisco perf port
+tr-rsrb-port 1996/tcp #cisco Remote SRB port
+tr-rsrb-port 1996/udp #cisco Remote SRB port
+gdp-port 1997/tcp #cisco Gateway Discovery Protocol
+gdp-port 1997/udp #cisco Gateway Discovery Protocol
+x25-svc-port 1998/tcp #cisco X.25 service (XOT)
+x25-svc-port 1998/udp #cisco X.25 service (XOT)
+tcp-id-port 1999/tcp #cisco identification port
+tcp-id-port 1999/udp #cisco identification port
+callbook 2000/tcp
+callbook 2000/udp
+dc 2001/tcp
+wizard 2001/udp #curry
+globe 2002/tcp
+globe 2002/udp
+cfingerd 2003/tcp #GNU finger
+mailbox 2004/tcp
+emce 2004/udp #CCWS mm conf
+berknet 2005/tcp
+oracle 2005/udp
+invokator 2006/tcp
+raid-cc 2006/udp #raid
+dectalk 2007/tcp
+raid-am 2007/udp
+conf 2008/tcp
+terminaldb 2008/udp
+news 2009/tcp
+whosockami 2009/udp
+search 2010/tcp
+pipe_server 2010/udp
+raid-cc 2011/tcp #raid
+servserv 2011/udp
+ttyinfo 2012/tcp
+raid-ac 2012/udp
+raid-am 2013/tcp
+raid-cd 2013/udp
+troff 2014/tcp
+raid-sf 2014/udp
+cypress 2015/tcp
+raid-cs 2015/udp
+bootserver 2016/tcp
+bootserver 2016/udp
+cypress-stat 2017/tcp
+bootclient 2017/udp
+terminaldb 2018/tcp
+rellpack 2018/udp
+whosockami 2019/tcp
+about 2019/udp
+xinupageserver 2020/tcp
+xinupageserver 2020/udp
+servexec 2021/tcp
+xinuexpansion1 2021/udp
+down 2022/tcp
+xinuexpansion2 2022/udp
+xinuexpansion3 2023/tcp
+xinuexpansion3 2023/udp
+xinuexpansion4 2024/tcp
+xinuexpansion4 2024/udp
+ellpack 2025/tcp
+xribs 2025/udp
+scrabble 2026/tcp
+scrabble 2026/udp
+shadowserver 2027/tcp
+shadowserver 2027/udp
+submitserver 2028/tcp
+submitserver 2028/udp
+device2 2030/tcp
+device2 2030/udp
+blackboard 2032/tcp
+blackboard 2032/udp
+glogger 2033/tcp
+glogger 2033/udp
+scoremgr 2034/tcp
+scoremgr 2034/udp
+imsldoc 2035/tcp
+imsldoc 2035/udp
+objectmanager 2038/tcp
+objectmanager 2038/udp
+lam 2040/tcp
+lam 2040/udp
+interbase 2041/tcp
+interbase 2041/udp
+isis 2042/tcp
+isis 2042/udp
+isis-bcast 2043/tcp
+isis-bcast 2043/udp
+rimsl 2044/tcp
+rimsl 2044/udp
+cdfunc 2045/tcp
+cdfunc 2045/udp
+sdfunc 2046/tcp
+sdfunc 2046/udp
+#dls 2047/tcp
+#dls 2047/udp
+dls-monitor 2048/tcp
+dls-monitor 2048/udp
+nfsd 2049/tcp nfs # NFS server daemon
+nfsd 2049/udp nfs # NFS server daemon
+#PROBLEMS!=============================================================
+#shilp 2049/tcp
+#shilp 2049/udp
+#PROBLEMS!=============================================================
+dlsrpn 2065/tcp #Data Link Switch Read Port Number
+dlsrpn 2065/udp #Data Link Switch Read Port Number
+dlswpn 2067/tcp #Data Link Switch Write Port Number
+dlswpn 2067/udp #Data Link Switch Write Port Number
+zephyr-clt 2103/udp #Zephyr serv-hm connection
+zephyr-hm 2104/udp #Zephyr hostmanager
+#PROBLEMS!=============================================================
+#zephyr-hm-srv 2105/udp #Zephyr hm-serv connection
+#PROBLEMS!=============================================================
+eklogin 2105/tcp #Kerberos (v4) encrypted rlogin
+eklogin 2105/udp #Kerberos (v4) encrypted rlogin
+ekshell 2106/tcp #Kerberos (v4) encrypted rshell
+ekshell 2106/udp #Kerberos (v4) encrypted rshell
+rkinit 2108/tcp #Kerberos (v4) remote initialization
+rkinit 2108/udp #Kerberos (v4) remote initialization
+ats 2201/tcp #Advanced Training System Program
+ats 2201/udp #Advanced Training System Program
+ivs-video 2232/tcp #IVS Video default
+ivs-video 2232/udp #IVS Video default
+ivsd 2241/tcp #IVS Daemon
+ivsd 2241/udp #IVS Daemon
+pehelp 2307/tcp
+pehelp 2307/udp
+cvspserver 2401/tcp #CVS network server
+cvspserver 2401/udp #CVS network server
+venus 2430/tcp #venus
+venus 2430/udp #venus
+venus-se 2431/tcp #venus-se
+venus-se 2431/udp #venus-se
+codasrv 2432/tcp #codasrv
+codasrv 2432/udp #codasrv
+codasrv-se 2433/tcp #codasrv-se
+codasrv-se 2433/udp #codasrv-se
+rtsserv 2500/tcp #Resource Tracking system server
+rtsserv 2500/udp #Resource Tracking system server
+rtsclient 2501/tcp #Resource Tracking system client
+rtsclient 2501/udp #Resource Tracking system client
+hp-3000-telnet 2564/tcp #HP 3000 NS/VT block mode telnet
+zebrasrv 2600/tcp #zebra service
+zebra 2601/tcp #zebra vty
+ripd 2602/tcp #RIPd vty
+ripngd 2603/tcp #RIPngd vty
+ospfd 2604/tcp #OSPFd vty
+bgpd 2605/tcp #BGPd vty
+ospf6d 2606/tcp #OSPF6d vty
+listen 2766/tcp #System V listener port
+www-dev 2784/tcp #world wide web - development
+www-dev 2784/udp #world wide web - development
+dict 2628/tcp #RFC 2229
+dict 2628/udp #RFC 2229
+eppc 3031/tcp #Remote AppleEvents/PPC Toolbox
+eppc 3031/udp #Remote AppleEvents/PPC Toolbox
+NSWS 3049/tcp
+NSWS 3049/udp
+sj3 3086/tcp #SJ3 (kanji input)
+vmodem 3141/tcp
+vmodem 3141/udp
+ccmail 3264/tcp #cc:mail/lotus
+ccmail 3264/udp #cc:mail/lotus
+dec-notes 3333/tcp #DEC Notes
+dec-notes 3333/udp #DEC Notes
+rsvp-encap 3455/udp #RSVP encapsulated in UDP
+mapper-nodemgr 3984/tcp #MAPPER network node manager
+mapper-nodemgr 3984/udp #MAPPER network node manager
+mapper-mapethd 3985/tcp #MAPPER TCP/IP server
+mapper-mapethd 3985/udp #MAPPER TCP/IP server
+mapper-ws_ethd 3986/tcp #MAPPER workstation server
+mapper-ws_ethd 3986/udp #MAPPER workstation server
+bmap 3421/tcp #Bull Apprise portmapper
+bmap 3421/udp #Bull Apprise portmapper
+prsvp 3455/tcp #RSVP Port
+prsvp 3455/udp #RSVP Port
+vat 3456/tcp #VAT default data
+vat 3456/udp #VAT default data
+vat-control 3457/tcp #VAT default control
+vat-control 3457/udp #VAT default control
+udt_os 3900/tcp #Unidata UDT OS
+udt_os 3900/udp #Unidata UDT OS
+netcheque 4008/tcp #NetCheque accounting
+netcheque 4008/udp #NetCheque accounting
+lockd 4045/udp # NFS lock daemon/manager
+lockd 4045/tcp
+nuts_dem 4132/tcp #NUTS Daemon
+nuts_dem 4132/udp #NUTS Daemon
+nuts_bootp 4133/tcp #NUTS Bootp Server
+nuts_bootp 4133/udp #NUTS Bootp Server
+rwhois 4321/tcp #Remote Who Is
+rwhois 4321/udp #Remote Who Is
+unicall 4343/tcp
+unicall 4343/udp
+krb524 4444/tcp
+krb524 4444/udp
+# PROBLEM krb524 assigned the port,
+# PROBLEM nv used it without an assignment
+nv-video 4444/tcp #NV Video default
+nv-video 4444/udp #NV Video default
+sae-urn 4500/tcp
+sae-urn 4500/udp
+fax 4557/tcp #FAX transmission service
+hylafax 4559/tcp #HylaFAX client-server protocol
+rfa 4672/tcp #remote file access server
+rfa 4672/udp #remote file access server
+commplex-main 5000/tcp
+commplex-main 5000/udp
+commplex-link 5001/tcp
+commplex-link 5001/udp
+rfe 5002/tcp #radio free ethernet
+rfe 5002/udp #radio free ethernet
+telelpathstart 5010/tcp
+telelpathstart 5010/udp
+telelpathattack 5011/tcp
+telelpathattack 5011/udp
+mmcc 5050/tcp #multimedia conference control tool
+mmcc 5050/udp #multimedia conference control tool
+rmonitor_secure 5145/tcp
+rmonitor_secure 5145/udp
+aol 5190/tcp #America-Online
+aol 5190/udp #America-Online
+aol-1 5191/tcp #AmericaOnline1
+aol-1 5191/udp #AmericaOnline1
+aol-2 5192/tcp #AmericaOnline2
+aol-2 5192/udp #AmericaOnline2
+aol-3 5193/tcp #AmericaOnline3
+aol-3 5193/udp #AmericaOnline3
+jabber-client 5222/tcp #Jabber Client Connection
+jabber-client 5222/udp #Jabber Client Connection
+padl2sim 5236/tcp
+padl2sim 5236/udp
+jabber-server 5269/tcp #Jabber Server Connection
+jabber-server 5269/udp #Jabber Server Connection
+hacl-hb 5300/tcp # HA cluster heartbeat
+hacl-hb 5300/udp # HA cluster heartbeat
+hacl-gs 5301/tcp # HA cluster general services
+hacl-gs 5301/udp # HA cluster general services
+hacl-cfg 5302/tcp # HA cluster configuration
+hacl-cfg 5302/udp # HA cluster configuration
+hacl-probe 5303/tcp # HA cluster probing
+hacl-probe 5303/udp # HA cluster probing
+hacl-local 5304/tcp
+hacl-local 5304/udp
+hacl-test 5305/tcp
+hacl-test 5305/udp
+cfengine 5308/tcp
+cfengine 5308/udp
+postgresql 5432/tcp #PostgreSQL Database
+postgresql 5432/udp #PostgreSQL Database
+rplay 5555/udp
+canna 5680/tcp #Canna (Japanese Input)
+proshareaudio 5713/tcp #proshare conf audio
+proshareaudio 5713/udp #proshare conf audio
+prosharevideo 5714/tcp #proshare conf video
+prosharevideo 5714/udp #proshare conf video
+prosharedata 5715/tcp #proshare conf data
+prosharedata 5715/udp #proshare conf data
+prosharerequest 5716/tcp #proshare conf request
+prosharerequest 5716/udp #proshare conf request
+prosharenotify 5717/tcp #proshare conf notify
+prosharenotify 5717/udp #proshare conf notify
+cvsup 5999/tcp #CVSup file transfer/John Polstra/FreeBSD
+x11 6000/tcp #6000-6063 are assigned to X Window System
+x11 6000/udp
+x11-ssh 6010/tcp #Unofficial name, for convenience
+x11-ssh 6010/udp
+softcm 6110/tcp #HP SoftBench CM
+softcm 6110/udp #HP SoftBench CM
+spc 6111/tcp #HP SoftBench Sub-Process Control
+spc 6111/udp #HP SoftBench Sub-Process Control
+meta-corp 6141/tcp #Meta Corporation License Manager
+meta-corp 6141/udp #Meta Corporation License Manager
+aspentec-lm 6142/tcp #Aspen Technology License Manager
+aspentec-lm 6142/udp #Aspen Technology License Manager
+watershed-lm 6143/tcp #Watershed License Manager
+watershed-lm 6143/udp #Watershed License Manager
+statsci1-lm 6144/tcp #StatSci License Manager - 1
+statsci1-lm 6144/udp #StatSci License Manager - 1
+statsci2-lm 6145/tcp #StatSci License Manager - 2
+statsci2-lm 6145/udp #StatSci License Manager - 2
+lonewolf-lm 6146/tcp #Lone Wolf Systems License Manager
+lonewolf-lm 6146/udp #Lone Wolf Systems License Manager
+montage-lm 6147/tcp #Montage License Manager
+montage-lm 6147/udp #Montage License Manager
+ricardo-lm 6148/tcp #Ricardo North America License Manager
+ricardo-lm 6148/udp #Ricardo North America License Manager
+xdsxdm 6558/tcp
+xdsxdm 6558/udp
+ircd 6667/tcp #Internet Relay Chat (unoffical)
+acmsoda 6969/tcp
+acmsoda 6969/udp
+afs3-fileserver 7000/tcp #file server itself
+afs3-fileserver 7000/udp #file server itself
+afs3-callback 7001/tcp #callbacks to cache managers
+afs3-callback 7001/udp #callbacks to cache managers
+afs3-prserver 7002/tcp #users & groups database
+afs3-prserver 7002/udp #users & groups database
+afs3-vlserver 7003/tcp #volume location database
+afs3-vlserver 7003/udp #volume location database
+afs3-kaserver 7004/tcp #AFS/Kerberos authentication service
+afs3-kaserver 7004/udp #AFS/Kerberos authentication service
+afs3-volser 7005/tcp #volume management server
+afs3-volser 7005/udp #volume management server
+afs3-errors 7006/tcp #error interpretation service
+afs3-errors 7006/udp #error interpretation service
+afs3-bos 7007/tcp #basic overseer process
+afs3-bos 7007/udp #basic overseer process
+afs3-update 7008/tcp #server-to-server updater
+afs3-update 7008/udp #server-to-server updater
+afs3-rmtsys 7009/tcp #remote cache manager service
+afs3-rmtsys 7009/udp #remote cache manager service
+afs3-resserver 7010/tcp #MR-AFS residence server
+afs3-resserver 7010/udp #MR-AFS residence server
+afs3-remio 7011/tcp #MR-AFS remote IO server
+afs3-remio 7011/udp #MR-AFS remote IO server
+ups-onlinet 7010/tcp #onlinet uninterruptable power supplies
+ups-onlinet 7010/udp #onlinet uninterruptable power supplies
+font-service 7100/tcp #X Font Service
+font-service 7100/udp #X Font Service
+fodms 7200/tcp #FODMS FLIP
+fodms 7200/udp #FODMS FLIP
+dlip 7201/tcp
+dlip 7201/udp
+natd 8668/divert # Network Address Translation
+jetdirect 9100/tcp #HP JetDirect card
+man 9535/tcp
+man 9535/udp
+sd 9876/tcp #Session Director
+sd 9876/udp #Session Director
+amanda 10080/udp #Dump server control
+amandaidx 10082/tcp #Amanda indexing
+amidxtape 10083/tcp #Amanda tape indexing
+isode-dua 17007/tcp
+isode-dua 17007/udp
+biimenu 18000/tcp #Beckman Instruments, Inc.
+biimenu 18000/udp #Beckman Instruments, Inc.
+dbbrowse 47557/tcp #Databeam Corporation
+dbbrowse 47557/udp #Databeam Corporation
+wnn4 22273/tcp #Wnn4 (Japanese input)
+wnn4_Cn 22289/tcp #Wnn4 (Chinese input)
+wnn4_Tw 22321/tcp #Wnn4 (Taiwanse input)
+wnn4_Kr 22305/tcp #Wnn4 (Korean input)
+wnn6 22273/tcp #Wnn6 (Japanese input)
+wnn6_Cn 22289/tcp #Wnn6 (Chinese input)
+wnn6_Tw 22321/tcp #Wnn6 (Taiwanse input)
+wnn6_Kr 22305/tcp #Wnn6 (Korean input)
+wnn6_DS 26208/tcp #Wnn6 (Dserver)
diff --git a/etc/shells b/etc/shells
new file mode 100644
index 0000000..ae7f33c
--- /dev/null
+++ b/etc/shells
@@ -0,0 +1,12 @@
+# $FreeBSD: src/etc/shells,v 1.5 2000/04/27 21:58:46 ache Exp $
+#
+# List of acceptable shells for chpass(1).
+# Ftpd will not allow users to connect who are not using
+# one of these shells.
+
+/bin/sh
+/bin/csh
+/bin/tcsh
+/usr/local/bin/bash
+/etc/rc.initial
+
diff --git a/etc/sshd b/etc/sshd
new file mode 100755
index 0000000..58c3dbe
--- /dev/null
+++ b/etc/sshd
@@ -0,0 +1,62 @@
+#! /usr/local/bin/php -f
+<?php
+/*
+ sshd - Modified to work on disk based system
+ Copyright 2004 Scott K Ullrich
+
+ Original Copyright (C) 2004 Fred Mol <fredmol@xs4all.nl>.
+ 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("config.inc");
+
+ $stderr = fopen("php://stderr", "w");
+ fwrite($stderr, "Initializing module ssh...\n");
+
+ if (!is_dir("/var/empty")) {
+ // Home directory of sshd.
+ mkdir("/var/empty", 0555);
+ }
+
+ if(!file_exists("")) {
+ // Login related files.
+ touch("/var/log/lastlog");
+ }
+
+ // Make the root password the same as the admin password of m0n0.
+ $fd = popen("/usr/sbin/pw usermod -n root -H 0", "w");
+ fwrite($fd, $config['system']['password']);
+ pclose($fd);
+
+ $sshConfigDir = "/etc/ssh";
+ if (!file_exists("$sshConfigDir/ssh_host_key")) {
+ system("/usr/bin/ssh-keygen -t rsa1 -N '' -f $sshConfigDir/ssh_host_key");
+ system("/usr/bin/ssh-keygen -t rsa -N '' -f $sshConfigDir/ssh_host_rsa_key");
+ system("/usr/bin/ssh-keygen -t dsa -N '' -f $sshConfigDir/ssh_host_dsa_key");
+ }
+
+ // And finally ...
+ system("sshd");
+ fwrite($stderr, "Done.\n");
+?>
+
diff --git a/etc/syslog.conf b/etc/syslog.conf
new file mode 100644
index 0000000..6b7fbd9
--- /dev/null
+++ b/etc/syslog.conf
@@ -0,0 +1,7 @@
+local0.* %/var/log/filter.log
+local3.* %/var/log/vpn.log
+local7.* %/var/log/dhcpd.log
+*.notice;kern.debug;lpr.info;mail.crit;news.err;local0.none;local3.none;local7.none %/var/log/system.log
+security.* %/var/log/system.log
+auth.info;authpriv.info;daemon.info %/var/log/system.log
+*.emerg *
diff --git a/etc/ttys b/etc/ttys
new file mode 100644
index 0000000..5cbe714
--- /dev/null
+++ b/etc/ttys
@@ -0,0 +1,291 @@
+#
+# $FreeBSD: src/etc/etc.i386/ttys,v 1.10 2003/10/24 15:44:08 simokawa Exp $
+# @(#)ttys 5.1 (Berkeley) 4/17/89
+#
+# This file specifies various information about terminals on the system.
+# It is used by several different programs. Common entries for the
+# various columns include:
+#
+# name The name of the terminal device.
+#
+# getty The program to start running on the terminal. Typically a
+# getty program, as the name implies. Other common entries
+# include none, when no getty is needed, and xdm, to start the
+# X Window System.
+#
+# type The initial terminal type for this port. For hardwired
+# terminal lines, this will contain the type of terminal used.
+# For virtual consoles, the correct type is typically cons25, but
+# vt220 will work better if you need interoperability with other
+# systems like Solaris or GNU/Linux.
+# Other common values include network for network connections on
+# pseudo-terminals, dialup for incoming modem ports, and unknown
+# when the terminal type cannot be predetermined.
+#
+# status Must be on or off. If on, init will run the getty program on
+# the specified port. If the word "secure" appears, this tty
+# allows root login.
+#
+# name getty type status comments
+#
+# If console is marked "insecure", then init will ask for the root password
+# when going to single-user mode.
+console none unknown off secure
+#
+ttyv0 "/usr/libexec/getty Pc" cons25 on secure
+ttyp0 none network
+ttyp1 none network
+ttyp2 none network
+ttyp3 none network
+ttyp4 none network
+ttyp5 none network
+ttyp6 none network
+ttyp7 none network
+ttyp8 none network
+ttyp9 none network
+ttypa none network
+ttypb none network
+ttypc none network
+ttypd none network
+ttype none network
+ttypf none network
+ttypg none network
+ttyph none network
+ttypi none network
+ttypj none network
+ttypk none network
+ttypl none network
+ttypm none network
+ttypn none network
+ttypo none network
+ttypp none network
+ttypq none network
+ttypr none network
+ttyps none network
+ttypt none network
+ttypu none network
+ttypv none network
+ttyq0 none network
+ttyq1 none network
+ttyq2 none network
+ttyq3 none network
+ttyq4 none network
+ttyq5 none network
+ttyq6 none network
+ttyq7 none network
+ttyq8 none network
+ttyq9 none network
+ttyqa none network
+ttyqb none network
+ttyqc none network
+ttyqd none network
+ttyqe none network
+ttyqf none network
+ttyqg none network
+ttyqh none network
+ttyqi none network
+ttyqj none network
+ttyqk none network
+ttyql none network
+ttyqm none network
+ttyqn none network
+ttyqo none network
+ttyqp none network
+ttyqq none network
+ttyqr none network
+ttyqs none network
+ttyqt none network
+ttyqu none network
+ttyqv none network
+ttyr0 none network
+ttyr1 none network
+ttyr2 none network
+ttyr3 none network
+ttyr4 none network
+ttyr5 none network
+ttyr6 none network
+ttyr7 none network
+ttyr8 none network
+ttyr9 none network
+ttyra none network
+ttyrb none network
+ttyrc none network
+ttyrd none network
+ttyre none network
+ttyrf none network
+ttyrg none network
+ttyrh none network
+ttyri none network
+ttyrj none network
+ttyrk none network
+ttyrl none network
+ttyrm none network
+ttyrn none network
+ttyro none network
+ttyrp none network
+ttyrq none network
+ttyrr none network
+ttyrs none network
+ttyrt none network
+ttyru none network
+ttyrv none network
+ttys0 none network
+ttys1 none network
+ttys2 none network
+ttys3 none network
+ttys4 none network
+ttys5 none network
+ttys6 none network
+ttys7 none network
+ttys8 none network
+ttys9 none network
+ttysa none network
+ttysb none network
+ttysc none network
+ttysd none network
+ttyse none network
+ttysf none network
+ttysg none network
+ttysh none network
+ttysi none network
+ttysj none network
+ttysk none network
+ttysl none network
+ttysm none network
+ttysn none network
+ttyso none network
+ttysp none network
+ttysq none network
+ttysr none network
+ttyss none network
+ttyst none network
+ttysu none network
+ttysv none network
+ttyP0 none network
+ttyP1 none network
+ttyP2 none network
+ttyP3 none network
+ttyP4 none network
+ttyP5 none network
+ttyP6 none network
+ttyP7 none network
+ttyP8 none network
+ttyP9 none network
+ttyPa none network
+ttyPb none network
+ttyPc none network
+ttyPd none network
+ttyPe none network
+ttyPf none network
+ttyPg none network
+ttyPh none network
+ttyPi none network
+ttyPj none network
+ttyPk none network
+ttyPl none network
+ttyPm none network
+ttyPn none network
+ttyPo none network
+ttyPp none network
+ttyPq none network
+ttyPr none network
+ttyPs none network
+ttyPt none network
+ttyPu none network
+ttyPv none network
+ttyQ0 none network
+ttyQ1 none network
+ttyQ2 none network
+ttyQ3 none network
+ttyQ4 none network
+ttyQ5 none network
+ttyQ6 none network
+ttyQ7 none network
+ttyQ8 none network
+ttyQ9 none network
+ttyQa none network
+ttyQb none network
+ttyQc none network
+ttyQd none network
+ttyQe none network
+ttyQf none network
+ttyQg none network
+ttyQh none network
+ttyQi none network
+ttyQj none network
+ttyQk none network
+ttyQl none network
+ttyQm none network
+ttyQn none network
+ttyQo none network
+ttyQp none network
+ttyQq none network
+ttyQr none network
+ttyQs none network
+ttyQt none network
+ttyQu none network
+ttyQv none network
+ttyR0 none network
+ttyR1 none network
+ttyR2 none network
+ttyR3 none network
+ttyR4 none network
+ttyR5 none network
+ttyR6 none network
+ttyR7 none network
+ttyR8 none network
+ttyR9 none network
+ttyRa none network
+ttyRb none network
+ttyRc none network
+ttyRd none network
+ttyRe none network
+ttyRf none network
+ttyRg none network
+ttyRh none network
+ttyRi none network
+ttyRj none network
+ttyRk none network
+ttyRl none network
+ttyRm none network
+ttyRn none network
+ttyRo none network
+ttyRp none network
+ttyRq none network
+ttyRr none network
+ttyRs none network
+ttyRt none network
+ttyRu none network
+ttyRv none network
+ttyS0 none network
+ttyS1 none network
+ttyS2 none network
+ttyS3 none network
+ttyS4 none network
+ttyS5 none network
+ttyS6 none network
+ttyS7 none network
+ttyS8 none network
+ttyS9 none network
+ttySa none network
+ttySb none network
+ttySc none network
+ttySd none network
+ttySe none network
+ttySf none network
+ttySg none network
+ttySh none network
+ttySi none network
+ttySj none network
+ttySk none network
+ttySl none network
+ttySm none network
+ttySn none network
+ttySo none network
+ttySp none network
+ttySq none network
+ttySr none network
+ttySs none network
+ttySt none network
+ttySu none network
+ttySv none network
diff --git a/etc/version b/etc/version
new file mode 100644
index 0000000..5b526c0
--- /dev/null
+++ b/etc/version
@@ -0,0 +1 @@
+1.2b2
diff --git a/usr/local/bin/runmsntp.sh b/usr/local/bin/runmsntp.sh
new file mode 100755
index 0000000..f7100b9
--- /dev/null
+++ b/usr/local/bin/runmsntp.sh
@@ -0,0 +1,12 @@
+#!/bin/sh
+
+# write our PID to file
+echo $$ > $1
+
+# execute msntp in endless loop; restart if it
+# exits (wait 1 second to avoid restarting too fast in case
+# the network is not yet setup)
+while true; do
+ /usr/local/bin/msntp -r -P no -l $2 -x $3 $4
+ sleep 1
+done
diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php
new file mode 100755
index 0000000..c264625
--- /dev/null
+++ b/usr/local/captiveportal/index.php
@@ -0,0 +1,407 @@
+#!/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("globals.inc");
+require("util.inc");
+require("config.inc");
+require("radius_authentication.inc") ;
+require("radius_accounting.inc") ;
+
+header("Expires: 0");
+header("Cache-Control: no-store, no-cache, must-revalidate");
+header("Cache-Control: post-check=0, pre-check=0", false);
+header("Pragma: no-cache");
+
+$orig_host = $_ENV['HTTP_HOST'];
+$orig_request = $_ENV['CAPTIVE_REQPATH'];
+$lockfile = "{$g['varrun_path']}/captiveportal.lock";
+$clientip = $_ENV['REMOTE_ADDR'];
+
+if (!$clientip) {
+ /* not good - bail out */
+ exit;
+}
+
+/* find MAC address for client */
+$clientmac = arp_get_mac_by_ip($clientip);
+if (!$clientmac && !isset($config['captiveportal']['nomacfilter'])) {
+ /* unable to find MAC address - shouldn't happen! - bail out */
+ exit;
+}
+
+if ($clientmac && portal_mac_fixed($clientmac)) {
+ /* punch hole in ipfw for pass thru mac addresses */
+ portal_allow($clientip, $clientmac, "unauthenticated");
+
+} else if ($_POST['accept'] && file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+
+ /* authenticate against radius server */
+ $radiusservers = captiveportal_get_radius_servers();
+
+ if ($_POST['auth_user'] && $_POST['auth_pass']) {
+ $auth_val = RADIUS_AUTHENTICATION($_POST['auth_user'],
+ $_POST['auth_pass'],
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['port'],
+ $radiusservers[0]['key']);
+ if ($auth_val == 2) {
+ $sessionid = portal_allow($clientip, $clientmac, $_POST['auth_user']);
+ if (isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ $auth_val = RADIUS_ACCOUNTING_START($_POST['auth_user'],
+ $sessionid,
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ } else {
+ readfile("{$g['varetc_path']}/captiveportal-error.html");
+ }
+ } else {
+ readfile("{$g['varetc_path']}/captiveportal-error.html");
+ }
+
+} else if ($_POST['accept'] && $clientip) {
+ portal_allow($clientip, $clientmac, "unauthenticated");
+} else if ($_POST['logout_id']) {
+ disconnect_client($_POST['logout_id']);
+ echo <<<EOD
+<HTML>
+<HEAD><TITLE>Disconnecting...</TITLE></HEAD>
+<BODY BGCOLOR="#435370">
+<SPAN STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
+<B>You've been disconnected.</B>
+</SPAN>
+<SCRIPT LANGUAGE="JavaScript">
+<!--
+setTimeout('window.close();',5000) ;
+-->
+</SCRIPT>
+</BODY>
+</HTML>
+
+EOD;
+} else if (($_ENV['SERVER_PORT'] != 8001) && isset($config['captiveportal']['httpslogin'])) {
+ /* redirect to HTTPS login page */
+ header("Location: https://{$config['captiveportal']['httpsname']}:8001/?redirurl=" . urlencode("http://{$orig_host}{$orig_request}"));
+} else {
+ /* display captive portal page */
+ $htmltext = file_get_contents("{$g['varetc_path']}/captiveportal.html");
+
+ /* substitute variables */
+ if (isset($config['captiveportal']['httpslogin']))
+ $htmltext = str_replace("\$PORTAL_ACTION\$", "https://{$config['captiveportal']['httpsname']}:8001/", $htmltext);
+ else
+ $htmltext = str_replace("\$PORTAL_ACTION\$", "", $htmltext);
+
+ if (preg_match("/redirurl=(.*)/", $orig_request, $matches))
+ $redirurl = urldecode($matches[1]);
+ else
+ $redirurl = "http://{$orig_host}{$orig_request}";
+ $htmltext = str_replace("\$PORTAL_REDIRURL\$", htmlspecialchars($redirurl), $htmltext);
+
+ echo $htmltext;
+}
+
+exit;
+
+function portal_mac_fixed($clientmac) {
+ global $g ;
+
+ /* open captive portal mac db */
+ if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) {
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db","r") ;
+ if (!$fd) {
+ return FALSE;
+ }
+ while (!feof($fd)) {
+ $mac = trim(fgets($fd)) ;
+ if(strcasecmp($clientmac, $mac) == 0) {
+ fclose($fd) ;
+ return TRUE ;
+ }
+ }
+ fclose($fd) ;
+ }
+ return FALSE ;
+}
+
+function portal_allow($clientip,$clientmac,$clientuser) {
+
+ global $orig_host, $orig_request, $g, $config;
+
+ /* user has accepted AUP - let him in */
+ portal_lock();
+
+ /* get next ipfw rule number */
+ if (file_exists("{$g['vardb_path']}/captiveportal.nextrule"))
+ $ruleno = trim(file_get_contents("{$g['vardb_path']}/captiveportal.nextrule"));
+ if (!$ruleno)
+ $ruleno = 10000; /* first rule number */
+
+ $saved_ruleno = $ruleno;
+
+ /* generate unique session ID */
+ $tod = gettimeofday();
+ $sessionid = substr(md5(mt_rand() . $tod['sec'] . $tod['usec'] . $clientip . $clientmac), 0, 16);
+
+ /* add ipfw rules for layer 3 */
+ exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from $clientip to any in");
+ exec("/sbin/ipfw add $ruleno set 2 skipto 50000 ip from any to $clientip out");
+
+ /* add ipfw rules for layer 2 */
+ if (!isset($config['captiveportal']['nomacfilter'])) {
+ $l2ruleno = $ruleno + 10000;
+ exec("/sbin/ipfw add $l2ruleno set 3 deny all from $clientip to any not MAC any $clientmac layer2 in");
+ exec("/sbin/ipfw add $l2ruleno set 3 deny all from any to $clientip not MAC $clientmac any layer2 out");
+ }
+
+ /* read in client database */
+ $cpdb = array();
+
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = trim(fgets($fd)) ;
+ if($line) {
+ $cpdb[] = explode(",",$line);
+ }
+ }
+ fclose($fd);
+ }
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* find an existing entry and delete it */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ if(!strcasecmp($cpdb[$i][2],$clientip)) {
+ if(isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $cpdb[$i][0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+
+ /* rewrite information to database */
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
+ if ($fd) {
+ foreach ($cpdb as $cpent) {
+ fwrite($fd, join(",", $cpent) . "\n");
+ }
+ /* write in this new entry */
+ fwrite($fd, time().",{$ruleno},{$clientip},{$clientmac},{$clientuser},{$sessionid}\n") ;
+ fclose($fd);
+ }
+
+ /* write next rule number */
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.nextrule", "w");
+ if ($fd) {
+ $ruleno++;
+ if ($ruleno > 19899)
+ $ruleno = 10000; /* wrap around */
+ fwrite($fd, $ruleno);
+ fclose($fd);
+ }
+
+ portal_unlock();
+
+ /* redirect user to desired destination */
+ if ($config['captiveportal']['redirurl'])
+ $redirurl = $config['captiveportal']['redirurl'];
+ else if ($_POST['redirurl'])
+ $redirurl = $_POST['redirurl'];
+ else
+ $redirurl = "http://{$orig_host}{$orig_request}";
+
+ if(isset($config['captiveportal']['logoutwin_enable'])) {
+
+ if (isset($config['captiveportal']['httpslogin']))
+ $logouturl = "https://{$config['captiveportal']['httpsname']}:8001/";
+ else
+ $logouturl = "http://{$config['interfaces'][$config['captiveportal']['interface']]['ipaddr']}:8000/";
+
+ echo <<<EOD
+<HTML>
+<HEAD><TITLE>Redirecting...</TITLE></HEAD>
+<BODY>
+<SPAN STYLE="font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">
+<B>Redirecting to <A HREF="{$redirurl}">{$redirurl}</A>...</B>
+</SPAN>
+<SCRIPT LANGUAGE="JavaScript">
+<!--
+LogoutWin = window.open('', 'Logout', 'toolbar=0,scrollbars=0,location=0,statusbar=0,menubar=0,resizable=0,width=256,height=64');
+if (LogoutWin) {
+ LogoutWin.document.write('<HTML>');
+ LogoutWin.document.write('<HEAD><TITLE>Logout</TITLE></HEAD>') ;
+ LogoutWin.document.write('<BODY BGCOLOR="#435370">');
+ LogoutWin.document.write('<DIV ALIGN="center" STYLE="color: #ffffff; font-family: Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size: 11px;">') ;
+ LogoutWin.document.write('<B>Click the button below to disconnect</B><P>');
+ LogoutWin.document.write('<FORM METHOD="POST" ACTION="{$logouturl}">');
+ LogoutWin.document.write('<INPUT NAME="logout_id" TYPE="hidden" VALUE="{$sessionid}">');
+ LogoutWin.document.write('<INPUT NAME="logout" TYPE="submit" VALUE="Logout">');
+ LogoutWin.document.write('</FORM>');
+ LogoutWin.document.write('</DIV></BODY>');
+ LogoutWin.document.write('</HTML>');
+ LogoutWin.document.close();
+}
+
+document.location.href="{$redirurl}";
+-->
+</SCRIPT>
+</BODY>
+</HTML>
+
+EOD;
+ } else {
+ header("Location: " . $redirurl);
+ }
+
+ return $sessionid;
+}
+
+/* read RADIUS servers into array */
+function captiveportal_get_radius_servers() {
+
+ global $g;
+
+ if (file_exists("{$g['vardb_path']}/captiveportal_radius.db")) {
+ $fd = @fopen("{$g['vardb_path']}/captiveportal_radius.db","r");
+ if ($fd) {
+ $radiusservers = array();
+ while (!feof($fd)) {
+ $line = trim(fgets($fd));
+ if ($line) {
+ $radsrv = array();
+ list($radsrv['ipaddr'],$radsrv['port'],$radsrv['acctport'],$radsrv['key']) = explode(",",$line);
+ $radiusservers[] = $radsrv;
+ }
+ }
+ fclose($fd);
+
+ return $radiusservers;
+ }
+ }
+
+ return false;
+}
+
+/* lock captive portal information, decide that the lock file is stale after
+ 10 seconds */
+function portal_lock() {
+
+ global $lockfile;
+
+ $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 captive portal information file */
+function portal_unlock() {
+
+ global $lockfile;
+
+ if (file_exists($lockfile))
+ unlink($lockfile);
+}
+
+/* remove a single client by session ID
+ by Dinesh Nair
+ */
+function disconnect_client($sessionid) {
+
+ global $g, $config;
+
+ portal_lock();
+
+ /* read database */
+ $cpdb = array() ;
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "r");
+ if ($fd) {
+ while (!feof($fd)) {
+ $line = trim(fgets($fd)) ;
+ if($line) {
+ $cpdb[] = explode(",",$line);
+ }
+ }
+ fclose($fd);
+ }
+
+ $radiusservers = captiveportal_get_radius_servers();
+
+ /* find entry */
+ for ($i = 0; $i < count($cpdb); $i++) {
+ if ($cpdb[$i][5] == $sessionid) {
+ /* this client needs to be deleted - remove ipfw rules */
+ if(isset($config['captiveportal']['radacct_enable']) && isset($radiusservers[0])) {
+ RADIUS_ACCOUNTING_STOP($cpdb[$i][1], // ruleno
+ $cpdb[$i][4], // username
+ $cpdb[$i][5], // sessionid
+ $cpdb[$i][0], // start time
+ $radiusservers[0]['ipaddr'],
+ $radiusservers[0]['acctport'],
+ $radiusservers[0]['key']);
+ }
+ mwexec("/sbin/ipfw delete " . $cpdb[$i][1] . " " . ($cpdb[$i][1]+10000));
+ unset($cpdb[$i]);
+ break;
+ }
+ }
+
+ /* rewrite information to database */
+ $fd = @fopen("{$g['vardb_path']}/captiveportal.db", "w");
+ if ($fd) {
+ foreach ($cpdb as $cpent) {
+ fwrite($fd, join(",", $cpent) . "\n");
+ }
+ fclose($fd);
+ }
+
+ portal_unlock();
+}
+?>
diff --git a/usr/local/captiveportal/radius_accounting.inc b/usr/local/captiveportal/radius_accounting.inc
new file mode 100644
index 0000000..7004971
--- /dev/null
+++ b/usr/local/captiveportal/radius_accounting.inc
@@ -0,0 +1,241 @@
+<?php
+/*
+ radius_accounting.inc
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
+ 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 RADIUS_ACCOUNTING_START($username,$sessionid,$radiusip,$radiusport,$radiuskey) {
+ $sharedsecret=$radiuskey ;
+ # $debug = 1 ;
+
+ exec("/bin/hostname", $nasHostname) ;
+ if(!$nasHostname[0])
+ $nasHostname[0] = "m0n0wall" ;
+
+ $fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
+ if(!$fd)
+ return 1 ; /* error return */
+
+ /* set 5 second timeout on socket i/o */
+ stream_set_timeout($fd, 5) ;
+
+ if ($debug)
+ echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
+
+ $thisidentifier=rand()%256;
+
+ $length=4+ // header
+ 16+ // auth code
+ 6+ // service type
+ 2+strlen($username)+ // username
+ 2+strlen($nasHostname[0])+ // nasIdentifier
+ 6+ // nasPort
+ 6+ // nasPortType
+ 6+ // Acct Status Type
+ 6+ // Acct RADIUS Authenticated
+ 2+strlen($sessionid); // Acct SessionID
+
+ // v v v v v v v v v 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 E
+ $data=pack("CCCCNNNNCCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ 0,0,0,0, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,1, // Acct Status Type = Start
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid // Acct Session ID
+ );
+
+ /* Generate Accounting Request Authenticator */
+ $RA = md5($data.$radiuskey) ;
+
+ // v v v v v v v v v 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 E
+ $data=pack("CCCCH*CCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ $RA, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,1, // Acct Status Type = Start
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid // Acct Session ID
+ );
+
+ if($debug) {
+ echo "username is $username with len " . strlen($username) ."\n" ;
+ echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
+ }
+
+ $ret = fwrite($fd,$data) ;
+ if( !$ret || ($ret != $length) )
+ return 1; /* error return */
+
+ if ($debug)
+ echo "<br>writing $length bytes<hr>\n";
+
+ $readdata = fgets($fd,2) ; /* read 1 byte */
+ $status = socket_get_status($fd) ;
+ fclose($fd) ;
+
+ if($status['timed_out'])
+ $retvalue = 1 ;
+ else
+ $retvalue = ord($readdata) ;
+
+ return $retvalue ;
+ // 5 -> Accounting-Response
+ // See RFC2866 for this.
+}
+
+function RADIUS_ACCOUNTING_STOP($ruleno,$username,$sessionid,$start_time,$radiusip,$radiusport,$radiuskey) {
+ $sharedsecret=$radiuskey ;
+ # $debug = 1 ;
+
+ exec("/bin/hostname", $nasHostname) ;
+ if(!$nasHostname[0])
+ $nasHostname[0] = "quewall" ;
+
+ $input_pkts = $input_bytes = $output_pkts = $output_bytes = 0 ;
+
+ exec("/sbin/ipfw show {$ruleno}", $ipfw) ;
+ preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+skipto/", $ipfw[0], $matches) ;
+ $output_pkts = $matches[2] ;
+ $output_bytes = $matches[3] ;
+
+ unset($matches) ;
+ preg_match("/(\d+)\s+(\d+)\s+(\d+)\s+skipto/", $ipfw[1], $matches) ;
+ $input_pkts = $matches[2] ;
+ $input_bytes = $matches[3] ;
+
+ $fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
+ if(!$fd)
+ return 1 ; /* error return */
+
+ /* set 5 second timeout on socket i/o */
+ stream_set_timeout($fd, 5) ;
+
+ if ($debug)
+ echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
+
+ $thisidentifier=rand()%256;
+
+ $length=4+ // header
+ 16+ // auth code
+ 6+ // service type
+ 2+strlen($username)+ // username
+ 2+strlen($nasHostname[0])+ // nasIdentifier
+ 6+ // nasPort
+ 6+ // nasPortType
+ 6+ // Acct Status Type
+ 6+ // Acct RADIUS Authenticated
+ 2+strlen($sessionid)+ // Acct SessionID
+ 6+ // Acct terminate
+ 6+ // Session time
+ 6+ // input bytes
+ 6+ // input packets
+ 6+ // output bytes
+ 6; // output packets
+
+ // v v v v v v v v v 1 1 1 1 1 1 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 E
+ $data=pack("CCCCNNNNCCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCNCCNCCNCCNCCNCCN",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ 0,0,0,0, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,2, // Acct Status Type = Stop
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid, // Acct Session ID
+ 49,6,1, // Acct Terminate = User Request
+ 46,6,time() - $start_time, // Session Time
+ 42,6,$input_bytes, // Input Octets
+ 47,6,$input_pkts, // Input Packets
+ 43,6,$output_bytes, // Output Octets
+ 48,6,$output_pkts // Output Packets
+ );
+
+ /* Generate Accounting Request Authenticator */
+ $RA = md5($data.$radiuskey) ;
+
+ // v v v v v v v v v 1 1 1 1 1 1 1 v
+ // Line # 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 E
+ $data=pack("CCCCH*CCCCCCCCa*CCa*CCCCCCCCCCCCCCCCCCCCCCCCCCa*CCNCCNCCNCCNCCNCCN",
+ 4,$thisidentifier,$length/256,$length%256, // header
+ $RA, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15, // nasPortType = Ethernet
+ 40,6,0,0,0,2, // Acct Status Type = Stop
+ 45,6,0,0,0,1, // Acct RADIUS Authenticated
+ 44,2+strlen($sessionid),$sessionid, // Acct Session ID
+ 49,6,1, // Acct Terminate = User Request
+ 46,6,time() - $start_time, // Session Time
+ 42,6,$input_bytes, // Input Octets
+ 47,6,$input_pkts, // Input Packets
+ 43,6,$output_bytes, // Output Octets
+ 48,6,$output_pkts // Output Packets
+ );
+
+ if($debug) {
+ echo "username is $username with len " . strlen($username) ."\n" ;
+ echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
+ }
+
+ $ret = fwrite($fd,$data) ;
+ if( !$ret || ($ret != $length) )
+ return 1; /* error return */
+
+ if ($debug)
+ echo "<br>writing $length bytes<hr>\n";
+
+ $readdata = fgets($fd,2) ; /* read 1 byte */
+ $status = socket_get_status($fd) ;
+ fclose($fd) ;
+
+ if($status['timed_out'])
+ $retvalue = 1 ;
+ else
+ $retvalue = ord($readdata) ;
+
+ return $retvalue ;
+ // 5 -> Accounting-Response
+ // See RFC2866 for this.
+}
+?>
diff --git a/usr/local/captiveportal/radius_authentication.inc b/usr/local/captiveportal/radius_authentication.inc
new file mode 100644
index 0000000..c106da3
--- /dev/null
+++ b/usr/local/captiveportal/radius_authentication.inc
@@ -0,0 +1,128 @@
+<?php
+ //
+ // $Id$
+ //
+ // radius authentication v1.0 by Edwin Groothuis (edwin@mavetju.org)
+ //
+ // If you didn't get this file via http://www.mavetju.org, please
+ // check for the availability of newer versions.
+ //
+ // See LICENSE for distribution issues. If this file isn't in
+ // the distribution, please inform me about it.
+ //
+ // If you want to use this script, fill in the configuration in
+ // radius_authentication.conf and call the function
+ // RADIUS_AUTHENTICATION() with the username and password
+ // provided by the user. If it returns a 2, the authentication
+ // was successfull!
+
+ // If you want to use this, make sure that you have raw sockets
+ // enabled during compile-time: "./configure --enable-sockets".
+
+ // This version has been modified by Dinesh Nair <dinesh@alphaque.com>
+ // for use in the m0n0wall distribution http://m0n0.ch/wall/
+ //
+ // Changes include moving from raw sockets to fsockopen
+ // and the removal of dependency on external conf file
+ // An existing bug which resulted in a malformed RADIUS packet
+ // was also fixed and patches submitted to Edwin. This bug would
+ // have caused authentication to fail on every access.
+
+function RADIUS_AUTHENTICATION($username,$password,$radiusip,$radiusport,$radiuskey) {
+ $sharedsecret=$radiuskey ;
+ # $debug = 1 ;
+
+ exec("/bin/hostname", $nasHostname) ;
+ if(!$nasHostname[0])
+ $nasHostname[0] = "m0n0wall" ;
+
+ $fd = @fsockopen("udp://$radiusip",$radiusport,$errno,$errstr,3) ;
+ if(!$fd)
+ return 1 ; /* error return */
+
+ /* set 5 second timeout on socket i/o */
+ stream_set_timeout($fd, 5) ;
+
+ if ($debug)
+ echo "<br>radius-port: $radiusport<br>radius-host: $radiusip<br>username: $username<hr>\n";
+
+ $RA=pack("CCCCCCCCCCCCCCCC", // auth code
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255,
+ 1+rand()%255, 1+rand()%255, 1+rand()%255, 1+rand()%255);
+
+ $encryptedpassword=Encrypt($password,$sharedsecret,$RA);
+
+ $length=4+ // header
+ 16+ // auth code
+ 6+ // service type
+ 2+strlen($username)+ // username
+ 2+strlen($encryptedpassword)+ // userpassword
+ 2+strlen($nasHostname[0])+ // nasIdentifier
+ 6+ // nasPort
+ 6; // nasPortType
+
+ $thisidentifier=rand()%256;
+ // v v v v v v v v v
+ // Line # 1 2 3 4 5 6 7 8 E
+ $data=pack("CCCCa*CCCCCCCCa*CCa*CCa*CCCCCCCCCCCC",
+ 1,$thisidentifier,$length/256,$length%256, // header
+ $RA, // authcode
+ 6,6,0,0,0,1, // service type
+ 1,2+strlen($username),$username, // username
+ 2,2+strlen($encryptedpassword),$encryptedpassword, // userpassword
+ 32,2+strlen($nasHostname[0]),$nasHostname[0], // nasIdentifier
+ 5,6,0,0,0,0, // nasPort
+ 61,6,0,0,0,15 // nasPortType = Ethernet
+ );
+
+ if($debug) {
+ echo "username is $username with len " . strlen($username) ."\n" ;
+ echo "encryptedpassword is $encryptedpassword with len " . strlen($encryptedpassword) ."\n" ;
+ echo "nasHostname is {$nasHostname[0]} with len " . strlen($nasHostname[0]) ."\n" ;
+ }
+
+ $ret = fwrite($fd,$data) ;
+ if( !$ret || ($ret != $length) )
+ return 1; /* error return */
+
+ if ($debug)
+ echo "<br>writing $length bytes<hr>\n";
+
+ $readdata = fgets($fd,2) ; /* read 1 byte */
+ $status = socket_get_status($fd) ;
+ fclose($fd) ;
+
+ if($status['timed_out'])
+ $retvalue = 1 ;
+ else
+ $retvalue = ord($readdata) ;
+
+ return $retvalue ;
+ // 2 -> Access-Accept
+ // 3 -> Access-Reject
+ // See RFC2865 for this.
+}
+
+function Encrypt($password,$key,$RA) {
+ global $debug;
+
+ $keyRA=$key.$RA;
+
+ if ($debug)
+ echo "<br>key: $key<br>password: $password<hr>\n";
+
+ $md5checksum=md5($keyRA);
+ $output="";
+
+ for ($i=0;$i<=15;$i++) {
+ if (2*$i>strlen($md5checksum)) $m=0; else $m=hexdec(substr($md5checksum,2*$i,2));
+ if ($i>strlen($keyRA)) $k=0; else $k=ord(substr($keyRA,$i,1));
+ if ($i>strlen($password)) $p=0; else $p=ord(substr($password,$i,1));
+ $c=$m^$p;
+ $output.=chr($c);
+ }
+ return $output;
+}
+?>
diff --git a/usr/local/etc/php.ini b/usr/local/etc/php.ini
new file mode 100644
index 0000000..3145b15
--- /dev/null
+++ b/usr/local/etc/php.ini
@@ -0,0 +1,10 @@
+magic_quotes_gpc = Off
+max_execution_time = 0
+max_input_time = 180
+register_argc_argv = Off
+file_uploads = On
+upload_tmp_dir = /ftmp
+upload_max_filesize = 6M
+post_max_size = 7M
+html_errors = Off
+include_path = ".:/etc/inc:/usr/local/www:/usr/local/captiveportal"
diff --git a/usr/local/lib/php.ini b/usr/local/lib/php.ini
new file mode 100644
index 0000000..3145b15
--- /dev/null
+++ b/usr/local/lib/php.ini
@@ -0,0 +1,10 @@
+magic_quotes_gpc = Off
+max_execution_time = 0
+max_input_time = 180
+register_argc_argv = Off
+file_uploads = On
+upload_tmp_dir = /ftmp
+upload_max_filesize = 6M
+post_max_size = 7M
+html_errors = Off
+include_path = ".:/etc/inc:/usr/local/www:/usr/local/captiveportal"
diff --git a/usr/local/sbin/ppp-linkup b/usr/local/sbin/ppp-linkup
new file mode 100755
index 0000000..01bca8e
--- /dev/null
+++ b/usr/local/sbin/ppp-linkup
@@ -0,0 +1,21 @@
+#!/bin/sh
+
+rm -f /var/etc/nameservers.conf
+
+# unset CGI environment variables so as not to confuse PHP
+unset CONTENT_TYPE GATEWAY_INTERFACE REMOTE_USER REMOTE_ADDR AUTH_TYPE
+unset HTTP_USER_AGENT CONTENT_LENGTH SCRIPT_FILENAME HTTP_HOST
+unset SERVER_SOFTWARE HTTP_REFERER SERVER_PROTOCOL REQUEST_METHOD
+unset SERVER_PORT SCRIPT_NAME SERVER_NAME
+
+# write nameservers to file
+if [ "$6" = "dns1" ]; then
+ echo $7 >> /var/etc/nameservers.conf
+fi
+if [ "$8" = "dns2" ]; then
+ echo $9 >> /var/etc/nameservers.conf
+fi
+
+# let the configuration system know that the
+# WAN IP address has changed
+/etc/rc.newwanip
diff --git a/usr/local/sbin/vpn-linkdown b/usr/local/sbin/vpn-linkdown
new file mode 100755
index 0000000..1147119
--- /dev/null
+++ b/usr/local/sbin/vpn-linkdown
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# record logout
+/usr/bin/logger -p local3.info "logout,$1,,$3"
+
+# resync ipfilter
+/sbin/ipf -y
diff --git a/usr/local/sbin/vpn-linkup b/usr/local/sbin/vpn-linkup
new file mode 100755
index 0000000..c56cb95
--- /dev/null
+++ b/usr/local/sbin/vpn-linkup
@@ -0,0 +1,7 @@
+#!/bin/sh
+
+# record login
+/usr/bin/logger -p local3.info "login,$1,$4,$5"
+
+# resync ipfilter
+/sbin/ipf -y
diff --git a/usr/local/www/diag_backup.php b/usr/local/www/diag_backup.php
new file mode 100755
index 0000000..888651c
--- /dev/null
+++ b/usr/local/www/diag_backup.php
@@ -0,0 +1,126 @@
+#!/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();
+
+ $fn = "config-" . $config['system']['hostname'] . "." .
+ $config['system']['domain'] . "-" . date("YmdHis") . ".xml";
+
+ $fs = filesize($g['conf_path'] . "/config.xml");
+ header("Content-Type: application/octet-stream");
+ header("Content-Disposition: attachment; filename=$fn");
+ 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><?=gentitle("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>
+ <form action="diag_backup.php" method="post" enctype="multipart/form-data">
+ <?php if ($input_errors) print_input_errors($input_errors); ?>
+ <?php if ($savemsg) print_info_box($savemsg); ?>
+ <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/usr/local/www/diag_defaults.php b/usr/local/www/diag_defaults.php
new file mode 100755
index 0000000..3ba3ea0
--- /dev/null
+++ b/usr/local/www/diag_defaults.php
@@ -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><?=gentitle("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($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/usr/local/www/diag_dhcp_leases.php b/usr/local/www/diag_dhcp_leases.php
new file mode 100755
index 0000000..4b730fa
--- /dev/null
+++ b/usr/local/www/diag_dhcp_leases.php
@@ -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><?=gentitle("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/usr/local/www/diag_ipsec_sad.php b/usr/local/www/diag_ipsec_sad.php
new file mode 100755
index 0000000..caba9d1
--- /dev/null
+++ b/usr/local/www/diag_ipsec_sad.php
@@ -0,0 +1,139 @@
+#!/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><?=gentitle("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>
+ <ul id="tabnav">
+ <li class="tabact">SAD</li>
+ <li class="tabinact"><a href="diag_ipsec_spd.php">SPD</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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/usr/local/www/diag_ipsec_spd.php b/usr/local/www/diag_ipsec_spd.php
new file mode 100755
index 0000000..80cd066
--- /dev/null
+++ b/usr/local/www/diag_ipsec_spd.php
@@ -0,0 +1,155 @@
+#!/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><?=gentitle("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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_ipsec_sad.php">SAD</a></li>
+ <li class="tabact">SPD</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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 if (is_array($cursp)) {
+ $linea = explode(" ", trim($line));
+ if ($i == 1) {
+ if ($linea[1] == "none") /* don't show default anti-lockout rule */
+ unset($cursp);
+ else
+ $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/usr/local/www/diag_logs.php b/usr/local/www/diag_logs.php
new file mode 100755
index 0000000..fe4d41a
--- /dev/null
+++ b/usr/local/www/diag_logs.php
@@ -0,0 +1,102 @@
+#!/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><?=gentitle("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>
+ <ul id="tabnav">
+ <li class="tabact">System</li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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/usr/local/www/diag_logs_dhcp.php b/usr/local/www/diag_logs_dhcp.php
new file mode 100755
index 0000000..ba13ee3
--- /dev/null
+++ b/usr/local/www/diag_logs_dhcp.php
@@ -0,0 +1,103 @@
+#!/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><?=gentitle("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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabact">DHCP</li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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/usr/local/www/diag_logs_filter.php b/usr/local/www/diag_logs_filter.php
new file mode 100755
index 0000000..fece0ac
--- /dev/null
+++ b/usr/local/www/diag_logs_filter.php
@@ -0,0 +1,190 @@
+#!/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";
+ }
+}
+
+function conv_clog($logfile, $tail) {
+ global $g, $config;
+
+ /* make interface/port table */
+ $iftable = array();
+ $iftable[$config['interfaces']['lan']['if']] = "LAN";
+ $iftable[get_real_wan_interface()] = "WAN";
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
+ $iftable[$config['interfaces']['opt' . $i]['if']] = $config['interfaces']['opt' . $i]['descr'];
+
+ $sor = isset($config['syslog']['reverse']) ? "-r" : "";
+
+ exec("/usr/sbin/clog " . $logfile . " | tail {$sor} -n " . $tail, $logarr);
+
+ $filterlog = array();
+
+ foreach ($logarr as $logent) {
+ $logent = preg_split("/\s+/", $logent, 6);
+ $ipfa = explode(" ", $logent[5]);
+
+ $flent = array();
+ $i = 0;
+ $flent['time'] = $ipfa[$i];
+ $i++;
+ if (substr($ipfa[$i], -1) == "x") {
+ $flent['count'] = substr($ipfa[$i], 0, -1);
+ $i++;
+ }
+ if ($iftable[$ipfa[$i]])
+ $flent['interface'] = $iftable[$ipfa[$i]];
+ else
+ $flent['interface'] = $ipfa[$i];
+ $i += 2;
+ $flent['act'] = $ipfa[$i];
+ $i++;
+ $flent['src'] = format_ipf_ip($ipfa[$i]);
+ $i += 2;
+ $flent['dst'] = format_ipf_ip($ipfa[$i]);
+ $i += 2;
+ $flent['proto'] = strtoupper($ipfa[$i]);
+
+ $filterlog[] = $flent;
+ }
+
+ return $filterlog;
+}
+
+function format_ipf_ip($ipfip) {
+ list($ip,$port) = explode(",", $ipfip);
+ if (!$port)
+ return $ip;
+
+ return $ip . ", port " . $port;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabact">Firewall</li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+<?php if (!isset($config['syslog']['rawfilter'])):
+ $filterlog = conv_clog("/var/log/filter.log", $nentries);
+?>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>
+ <td colspan="6" class="listtopic">
+ Last <?=$nentries;?> firewall log entries</td>
+ </tr>
+ <tr>
+ <td width="10%" class="listhdrr">Act</td>
+ <td width="20%" class="listhdrr">Time</td>
+ <td width="10%" class="listhdrr">If</td>
+ <td width="20%" class="listhdrr">Source</td>
+ <td width="20%" class="listhdrr">Destination</td>
+ <td width="10%" class="listhdrr">Proto</td>
+ </tr><?php foreach ($filterlog as $filterent): ?>
+ <tr>
+ <td class="listlr" nowrap>
+ <?php if (strstr(strtolower($filterent['act']), "p"))
+ $img = "pass.gif";
+ else
+ $img = "block.gif";
+ ?>
+ <img src="<?=$img;?>" width="11" height="11" align="absmiddle">
+ <?php if ($filterent['count']) echo $filterent['count'];?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['time']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['interface']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['src']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['dst']);?></td>
+ <td class="listr" nowrap><?=htmlspecialchars($filterent['proto']);?></td>
+ </tr><?php endforeach; ?>
+ </table>
+<?php else: ?>
+ <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>
+<?php endif; ?>
+ <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/usr/local/www/diag_logs_settings.php b/usr/local/www/diag_logs_settings.php
new file mode 100755
index 0000000..7868c56
--- /dev/null
+++ b/usr/local/www/diag_logs_settings.php
@@ -0,0 +1,202 @@
+#!/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['vpn'] = isset($config['syslog']['vpn']);
+$pconfig['system'] = isset($config['syslog']['system']);
+$pconfig['enable'] = isset($config['syslog']['enable']);
+$pconfig['logdefaultblock'] = !isset($config['syslog']['nologdefaultblock']);
+$pconfig['rawfilter'] = isset($config['syslog']['rawfilter']);
+
+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']['vpn'] = $_POST['vpn'] ? 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;
+ $config['syslog']['rawfilter'] = $_POST['rawfilter'] ? true : false;
+
+ 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><?=gentitle("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.vpn.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.vpn.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>
+<form action="diag_logs_settings.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabinact"><a href="diag_logs_vpn.php">PPTP VPN</a></li>
+ <li class="tabact">Settings</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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 valign="top" class="vtable">&nbsp;</td>
+ <td class="vtable"> <input name="rawfilter" type="checkbox" id="rawfilter" value="yes" <?php if ($pconfig['rawfilter']) echo "checked"; ?>>
+ <strong>Show raw filter logs</strong><br>
+ Hint: If this is checked, filter logs are shown as generated by the packet filter, without any formatting. This will reveal more detailed information. </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<br> <input name="vpn" id="vpn" type="checkbox" value="yes" <?php if ($pconfig['vpn']) echo "checked"; ?>>
+ PPTP VPN 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/usr/local/www/diag_logs_vpn.php b/usr/local/www/diag_logs_vpn.php
new file mode 100755
index 0000000..3ed561c
--- /dev/null
+++ b/usr/local/www/diag_logs_vpn.php
@@ -0,0 +1,111 @@
+#!/usr/local/bin/php
+<?php
+/*
+ diag_logs_vpn.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 65536 /var/log/vpn.log");
+}
+
+function dump_clog($logfile, $tail) {
+ 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);
+ $llent = explode(",", $logent[5]);
+
+ echo "<tr>\n";
+ echo "<td class=\"listlr\" nowrap>" . htmlspecialchars(join(" ", array_slice($logent, 0, 3))) . "</td>\n";
+
+ if ($llent[0] == "login")
+ echo "<td class=\"listr\"><img src=\"in.gif\" width=\"11\" height=\"11\" title=\"login\"></td>\n";
+ else
+ echo "<td class=\"listr\"><img src=\"out.gif\" width=\"11\" height=\"11\" title=\"logout\"></td>\n";
+
+ echo "<td class=\"listr\">" . htmlspecialchars($llent[3]) . "</td>\n";
+ echo "<td class=\"listr\">" . htmlspecialchars($llent[2]) . "&nbsp;</td>\n";
+ echo "</tr>\n";
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="diag_logs.php">System</a></li>
+ <li class="tabinact"><a href="diag_logs_filter.php">Firewall</a></li>
+ <li class="tabinact"><a href="diag_logs_dhcp.php">DHCP</a></li>
+ <li class="tabact">PPTP VPN</li>
+ <li class="tabinact"><a href="diag_logs_settings.php">Settings</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0"><tr>
+ <td colspan="4" class="listtopic">
+ Last <?=$nentries;?> firewall log entries</td>
+ </tr>
+ <tr>
+ <td class="listhdrr">Time</td>
+ <td class="listhdrr">Action</td>
+ <td class="listhdrr">User</td>
+ <td class="listhdrr">IP address</td>
+ </tr>
+ <?php dump_clog("/var/log/vpn.log", $nentries); ?>
+ </table>
+ <br><form action="diag_logs_vpn.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/usr/local/www/diag_ping.php b/usr/local/www/diag_ping.php
new file mode 100755
index 0000000..33ad4ac
--- /dev/null
+++ b/usr/local/www/diag_ping.php
@@ -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><?=gentitle("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/usr/local/www/diag_resetstate.php b/usr/local/www/diag_resetstate.php
new file mode 100755
index 0000000..3a7f028
--- /dev/null
+++ b/usr/local/www/diag_resetstate.php
@@ -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><?=gentitle("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($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/usr/local/www/edit.php b/usr/local/www/edit.php
new file mode 100755
index 0000000..694f40b
--- /dev/null
+++ b/usr/local/www/edit.php
@@ -0,0 +1,128 @@
+#!/usr/local/bin/php
+<?php
+if (($_POST['submit'] == "Load") && file_exists($_POST['savetopath'])) {
+ $fd = fopen($_POST['savetopath'], "r");
+ $content = fread($fd, filesize($_POST['savetopath']));
+ fclose($fd);
+ $edit_area="";
+ $ulmsg = "Loaded text from " . $_POST['savetopath'];
+} else if (($_POST['submit'] == "Save")) {
+ $content = ereg_replace("\r","",$_POST['content']) ;
+ $fd = fopen($_POST['savetopath'], "w");
+ fwrite($fd, $content);
+ fclose($fd);
+ $edit_area="";
+ $ulmsg = "Saved text to " . $_POST['savetopath'];
+} else if (($_POST['submit'] == "Load") && !file_exists($_POST['savetopath'])) {
+ $ulmsg = "File not found " . $_POST['savetopath'];
+ $content = "";
+ $_POST['savetopath'] = "";
+}
+
+if($_POST['rows'] <> "")
+ $rows = $_POST['rows'];
+else
+ $rows = 40;
+
+if($_POST['cols'] <> "")
+ $cols = $_POST['cols'];
+else
+ $cols = 80;
+?>
+<!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>)
+ (modified for pfSense Edit/Save file by Scott Ullrich, Copyright 2004)
+*/
+
+// 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 = 'pfSense: edit file';
+
+// Get year.
+
+$arrDT = localtime();
+$intYear = $arrDT[5] + 1900;
+
+?>
+<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<title><?=$Title ?></title>
+<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 ($ulmsg) echo "<p><strong>" . $ulmsg . "</strong></p>\n"; ?>
+
+<form action="<?=$ScriptName ?>" method="POST">
+ <table>
+ <tr>
+ <td>
+ Save/Load from path: <input name="savetopath" value="<?php echo $_POST['savetopath']; ?>">
+ Rows: <input size="3" name="rows" value="<? echo $rows; ?>">
+ Cols: <input size="3" name="cols" value="<? echo $cols; ?>">
+ <input name="submit" type="submit" class="button" id="Load" value="Load">
+ <br><hr noshade width=100%>
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="label">
+ <textarea rows="<?php echo $rows; ?>" cols="<?php echo $cols; ?>" name="content"><?php echo $content; ?></textarea><br>
+ <p>
+ <center><input name="submit" type="submit" class="button" id="Save" value="Save"></center></td>
+ </tr>
+ </table>
+</form>
+</body>
+</html>
+
diff --git a/usr/local/www/exec.php b/usr/local/www/exec.php
new file mode 100755
index 0000000..8f47fc5
--- /dev/null
+++ b/usr/local/www/exec.php
@@ -0,0 +1,240 @@
+#!/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 to /tmp/" . htmlentities($_FILES['ulfile']['name']);
+ 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");
+ putenv("SCRIPT_FILENAME=" . strtok($_POST['txtCommand'], " ")); /* PHP scripts */
+ $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/usr/local/www/exec_raw.php b/usr/local/www/exec_raw.php
new file mode 100755
index 0000000..6d1ca34
--- /dev/null
+++ b/usr/local/www/exec_raw.php
@@ -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/usr/local/www/fbegin.inc b/usr/local/www/fbegin.inc
new file mode 100755
index 0000000..1aae7f1
--- /dev/null
+++ b/usr/local/www/fbegin.inc
@@ -0,0 +1,131 @@
+<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">
+ <table border="0" cellspacing="0" cellpadding="0" width="100%">
+ <tr><td align="left" valign="bottom"><span class="tfrtitle">&nbsp;webGUI
+ Configuration</span></td>
+ <td align="right" valign="bottom">
+ <span class="hostname"><?=$config['system']['hostname'] . "." . $config['system']['domain'];?>&nbsp;</span>
+ </td></tr></table>
+ </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++): if (!isset($config['interfaces']['opt' . $i]['ovpn'])): ?>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/interfaces_opt.php?index=<?=$i;?>" class="navlnk"><?=htmlspecialchars($config['interfaces']['opt' . $i]['descr']);?></a><br>
+ <?php endif; 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_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 server</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_dhcp_relay.php" class="navlnk">DHCP relay</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>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_captiveportal.php" class="navlnk">Captive portal</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/services_wol.php" class="navlnk">Wake on LAN</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;<a href="/vpn_openvpn.php" class="navlnk">OpenVPN</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_graph.php" class="navlnk">Traffic graph</a><br>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_wireless.php" class="navlnk">Wireless</a><br>
+ <?php if (isset($config['captiveportal']['enable'])): ?>
+ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;<a href="/status_captiveportal.php" class="navlnk">Captive portal</a><br>
+ <?php endif; ?>
+<?php
+/* extensions section */
+if (is_dir("{$g['www_path']}/ext")):
+?>
+ <strong>Extensions</strong><br>
+<?php
+$dh = @opendir("{$g['www_path']}/ext");
+if ($dh) {
+ while (($extd = readdir($dh)) !== false) {
+ if (($extd === ".") || ($extd === ".."))
+ continue;
+ @include("{$g['www_path']}/ext/" . $extd . "/menu.inc");
+ }
+ closedir($dh);
+}
+endif;
+?>
+ <?php if (isset($config['system']['webgui']['expanddiags']) || 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>
diff --git a/usr/local/www/fend.inc b/usr/local/www/fend.inc
new file mode 100755
index 0000000..871ec68
--- /dev/null
+++ b/usr/local/www/fend.inc
@@ -0,0 +1,8 @@
+</td></tr></table></td>
+ </tr>
+ <tr align="center" valign="top" bgcolor="#435370">
+ <td colspan="2" class="cpline">pfSense is &copy; 2004 by Scott Ullrich. All Rights Reserved.
+<br>pfSense is originally based on m0n0wall which is &copy; 2002-2004 by Manuel Kasper.
+ All rights reserved.&nbsp; [<a href="/license.php" class="tblnk">view license</a>]</td>
+ </tr>
+</table>
diff --git a/usr/local/www/firewall_aliases.php b/usr/local/www/firewall_aliases.php
new file mode 100755
index 0000000..cb94725
--- /dev/null
+++ b/usr/local/www/firewall_aliases.php
@@ -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><?=gentitle("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($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/usr/local/www/firewall_aliases_edit.php b/usr/local/www/firewall_aliases_edit.php
new file mode 100755
index 0000000..8955197
--- /dev/null
+++ b/usr/local/www/firewall_aliases_edit.php
@@ -0,0 +1,195 @@
+#!/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><?=gentitle("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); ?>
+ <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/usr/local/www/firewall_nat.php b/usr/local/www/firewall_nat.php
new file mode 100755
index 0000000..1708ef8
--- /dev/null
+++ b/usr/local/www/firewall_nat.php
@@ -0,0 +1,171 @@
+#!/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><?=gentitle("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($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>
+ <ul id="tabnav">
+ <li class="tabact">Inbound</li>
+ <li class="tabinact"><a href="firewall_nat_server.php">Server NAT</a></li>
+ <li class="tabinact"><a href="firewall_nat_1to1.php">1:1</a></li>
+ <li class="tabinact"><a href="firewall_nat_out.php">Outbound</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="5%" class="listhdrr">If</td>
+ <td width="5%" class="listhdrr">Proto</td>
+ <td width="20%" class="listhdrr">Ext. port range</td>
+ <td width="20%" class="listhdrr">NAT IP</td>
+ <td width="20%" class="listhdrr">Int. port range</td>
+ <td width="20%" class="listhdr">Description</td>
+ <td width="5%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_nat as $natent): ?>
+ <tr valign="top">
+ <td class="listlr">
+ <?php
+ if (!$natent['interface'] || ($natent['interface'] == "wan"))
+ echo "WAN";
+ else
+ echo htmlspecialchars($config['interfaces'][$natent['interface']]['descr']);
+ ?>
+ </td>
+ <td class="listr">
+ <?=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>(ext.: " . $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="6"></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/usr/local/www/firewall_nat_1to1.php b/usr/local/www/firewall_nat_1to1.php
new file mode 100755
index 0000000..f4d2e20
--- /dev/null
+++ b/usr/local/www/firewall_nat_1to1.php
@@ -0,0 +1,145 @@
+#!/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><?=gentitle("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($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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_nat.php">Inbound</a></li>
+ <li class="tabinact"><a href="firewall_nat_server.php">Server NAT</a></li>
+ <li class="tabact">1:1</li>
+ <li class="tabinact"><a href="firewall_nat_out.php">Outbound</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="10%" class="listhdrr">Interface</td>
+ <td width="20%" class="listhdrr">External IP</td>
+ <td width="20%" class="listhdrr">Internal IP</td>
+ <td width="40%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_1to1 as $natent): ?>
+ <tr>
+ <td class="listlr">
+ <?php
+ if (!$natent['interface'] || ($natent['interface'] == "wan"))
+ echo "WAN";
+ else
+ echo htmlspecialchars($config['interfaces'][$natent['interface']]['descr']);
+ ?>
+ </td>
+ <td class="listr">
+ <?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="4"></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/usr/local/www/firewall_nat_1to1_edit.php b/usr/local/www/firewall_nat_1to1_edit.php
new file mode 100755
index 0000000..7361c92
--- /dev/null
+++ b/usr/local/www/firewall_nat_1to1_edit.php
@@ -0,0 +1,216 @@
+#!/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'];
+ $pconfig['interface'] = $a_1to1[$id]['interface'];
+ if (!$pconfig['interface'])
+ $pconfig['interface'] = "wan";
+ 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;
+ $pconfig['interface'] = "wan";
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface external internal");
+ $reqdfieldsn = explode(",", "Interface,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'];
+ $natent['interface'] = $_POST['interface'];
+
+ 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><?=gentitle("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); ?>
+ <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">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="interface" class="formfld">
+ <?php
+ $interfaces = array('wan' => 'WAN');
+ 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 rule applies to.<br>
+ Hint: in most cases, you'll want to use WAN here.</span></td>
+ </tr>
+ <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/usr/local/www/firewall_nat_edit.php b/usr/local/www/firewall_nat_edit.php
new file mode 100755
index 0000000..d80865f
--- /dev/null
+++ b/usr/local/www/firewall_nat_edit.php
@@ -0,0 +1,365 @@
+#!/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'];
+ $pconfig['interface'] = $a_nat[$id]['interface'];
+ if (!$pconfig['interface'])
+ $pconfig['interface'] = "wan";
+} else {
+ $pconfig['interface'] = "wan";
+}
+
+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(" ", "interface proto beginport localip localbeginport");
+ $reqdfieldsn = explode(",", "Interface,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;
+ }
+
+ if (!$input_errors) {
+ if (($_POST['endport'] - $_POST['beginport'] + $_POST['localbeginport']) > 65535)
+ $input_errors[] = "The target port range must lie between 1 and 65535.";
+ }
+
+ /* check for overlaps */
+ foreach ($a_nat as $natent) {
+ if (isset($id) && ($a_nat[$id]) && ($a_nat[$id] === $natent))
+ continue;
+ if ($natent['interface'] != $_POST['interface'])
+ 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['interface'] = $_POST['interface'];
+ $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'] = $_POST['interface'];
+ $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><?=gentitle("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); ?>
+ <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">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="interface" class="formfld">
+ <?php
+ $interfaces = array('wan' => 'WAN');
+ 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 rule applies to.<br>
+ Hint: in most cases, you'll want to use WAN here.</span></td>
+ </tr>
+ <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"; ?>>Interface address</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 the IP address of the interface chosen above,
+ 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/usr/local/www/firewall_nat_out.php b/usr/local/www/firewall_nat_out.php
new file mode 100755
index 0000000..978f3b3
--- /dev/null
+++ b/usr/local/www/firewall_nat_out.php
@@ -0,0 +1,184 @@
+#!/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><?=gentitle("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($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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_nat.php">Inbound</a></li>
+ <li class="tabinact"><a href="firewall_nat_server.php">Server NAT</a></li>
+ <li class="tabinact"><a href="firewall_nat_1to1.php">1:1</a></li>
+ <li class="tabact">Outbound</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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="10%" class="listhdrr">Interface</td>
+ <td width="20%" class="listhdrr">Source</td>
+ <td width="20%" class="listhdrr">Destination</td>
+ <td width="20%" class="listhdrr">Target</td>
+ <td width="25%" class="listhdr">Description</td>
+ <td width="5%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_out as $natent): ?>
+ <tr>
+ <td class="listlr">
+ <?php
+ if (!$natent['interface'] || ($natent['interface'] == "wan"))
+ echo "WAN";
+ else
+ echo htmlspecialchars($config['interfaces'][$natent['interface']]['descr']);
+ ?>
+ </td>
+ <td class="listr">
+ <?=$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="5"></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/usr/local/www/firewall_nat_out_edit.php b/usr/local/www/firewall_nat_out_edit.php
new file mode 100755
index 0000000..723de78
--- /dev/null
+++ b/usr/local/www/firewall_nat_out_edit.php
@@ -0,0 +1,311 @@
+#!/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['interface'] = $a_out[$id]['interface'];
+ if (!$pconfig['interface'])
+ $pconfig['interface'] = "wan";
+ $pconfig['descr'] = $a_out[$id]['descr'];
+} else {
+ $pconfig['source_subnet'] = 24;
+ $pconfig['destination'] = "any";
+ $pconfig['destination_subnet'] = 24;
+ $pconfig['interface'] = "wan";
+}
+
+if ($_POST) {
+
+ if ($_POST['destination_type'] == "any") {
+ $_POST['destination'] = "any";
+ $_POST['destination_subnet'] = 24;
+ }
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface source source_subnet destination destination_subnet");
+ $reqdfieldsn = explode(",", "Interface,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['interface'])
+ $natent['interface'] == "wan";
+
+ if (($natent['interface'] == $_POST['interface']) && ($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'];
+ $natent['interface'] = $_POST['interface'];
+
+ 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><?=gentitle("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); ?>
+ <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">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="interface" class="formfld">
+ <?php
+ $interfaces = array('wan' => 'WAN');
+ 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 rule applies to.<br>
+ Hint: in most cases, you'll want to use WAN here.</span></td>
+ </tr>
+ <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 selected 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/usr/local/www/firewall_nat_server.php b/usr/local/www/firewall_nat_server.php
new file mode 100755
index 0000000..11f44b6
--- /dev/null
+++ b/usr/local/www/firewall_nat_server.php
@@ -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><?=gentitle("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($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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_nat.php">Inbound</a></li>
+ <li class="tabact">Server NAT</li>
+ <li class="tabinact"><a href="firewall_nat_1to1.php">1:1</a></li>
+ <li class="tabinact"><a href="firewall_nat_out.php">Outbound</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="80%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="40%" class="listhdrr">External IP address</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/usr/local/www/firewall_nat_server_edit.php b/usr/local/www/firewall_nat_server_edit.php
new file mode 100755
index 0000000..4ed1f2d
--- /dev/null
+++ b/usr/local/www/firewall_nat_server_edit.php
@@ -0,0 +1,153 @@
+#!/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]) {
+ /* modify all inbound NAT rules with this address */
+ for ($i = 0; isset($config['nat']['rule'][$i]); $i++) {
+ if ($config['nat']['rule'][$i]['external-address'] == $a_snat[$id]['ipaddr'])
+ $config['nat']['rule'][$i]['external-address'] = $natent['ipaddr'];
+ }
+ $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><?=gentitle("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); ?>
+ <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 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="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/usr/local/www/firewall_rules.php b/usr/local/www/firewall_rules.php
new file mode 100755
index 0000000..cd3424c
--- /dev/null
+++ b/usr/local/www/firewall_rules.php
@@ -0,0 +1,268 @@
+#!/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;
+ }
+} else if ($_GET['act'] == "toggle") {
+ if ($a_filter[$_GET['id']]) {
+ $a_filter[$_GET['id']]['disabled'] = !isset($a_filter[$_GET['id']]['disabled']);
+ 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><?=gentitle("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($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">
+
+ <tr><td colspan="9">
+ <ul id="tabnav">
+ <li class="tabact">Rules</li>
+ <li class="tabinact"><a href="firewall_shaper_queues.php">Queues</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <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]['name'] . " 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'])) {
+ $textss = "<span class=\"gray\">";
+ $textse = "</span>";
+ $iconfn .= "_d";
+ } else {
+ $textss = $textse = "";
+ }
+ ?>
+ <a href="?act=toggle&id=<?=$i;?>"><img src="<?=$iconfn;?>.gif" width="11" height="11" border="0" title="click to toggle enabled/disabled status"></a>
+ <?php if (isset($filterent['log'])):
+ $iconfn = "log_s";
+ if (isset($filterent['disabled']))
+ $iconfn .= "_d";
+ ?>
+ <br><img src="<?=$iconfn;?>.gif" width="11" height="15" border="0">
+ <?php endif; ?>
+ </td>
+ <td class="listlr">
+ <?=$textss;?><?php if (isset($filterent['protocol'])) echo strtoupper($filterent['protocol']); else echo "*"; ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_address($filterent['source'])); ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_port($filterent['source']['port'])); ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_address($filterent['destination'])); ?><?=$textse;?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php echo htmlspecialchars(pprint_port($filterent['destination']['port'])); ?><?=$textse;?>
+ </td>
+ <td class="listbg">
+ <?=$textss;?><?=htmlspecialchars($filterent['name']);?>&nbsp;<?=$textse;?>
+ </td>
+ <td valign="middle" nowrap class="list">
+ <a href="firewall_rules_edit.php?id=<?=$i;?>"><img src="e.gif" title="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" title="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" title="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" title="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" title="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" title="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>
+ </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/usr/local/www/firewall_rules_edit.php b/usr/local/www/firewall_rules_edit.php
new file mode 100755
index 0000000..620ea6e
--- /dev/null
+++ b/usr/local/www/firewall_rules_edit.php
@@ -0,0 +1,773 @@
+#!/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";
+
+ if ($a_filter[$id]['protocol'] == "icmp")
+ $pconfig['icmptype'] = $a_filter[$id]['icmptype'];
+
+ 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']);
+
+ if ($_POST['proto'] == "icmp" && $_POST['icmptype'])
+ $filterent['icmptype'] = $_POST['icmptype'];
+ else
+ unset($filterent['icmptype']);
+
+ 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;
+ }
+
+ /* ALTQ */
+ $filterent['direction'] = $_POST['direction'];
+ $filterent['queue'] = $_POST['queue'];
+
+ 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><?=gentitle("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;
+ }
+
+ if (document.iform.proto.selectedIndex == 3) {
+ document.iform.icmptype.disabled = 0;
+ } else {
+ document.iform.icmptype.disabled = 1;
+ }
+
+ 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); ?>
+ <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 IGMP 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 valign="top" class="vncell">ICMP type</td>
+ <td class="vtable">
+ <select name="icmptype" class="formfld">
+ <?php
+
+ $icmptypes = array(
+ "" => "any",
+ "unreach" => "Destination unreachable",
+ "echo" => "Echo",
+ "echorep" => "Echo reply",
+ "squench" => "Source quench",
+ "redir" => "Redirect",
+ "timex" => "Time exceeded",
+ "paramprob" => "Parameter problem",
+ "timest" => "Timestamp",
+ "timestrep" => "Timestamp reply",
+ "inforeq" => "Information request",
+ "inforep" => "Information reply",
+ "maskreq" => "Address mask request",
+ "maskrep" => "Address mask reply"
+ );
+
+ foreach ($icmptypes as $icmptype => $descr): ?>
+ <option value="<?=$icmptype;?>" <?php if ($icmptype == $pconfig['icmptype']) echo "selected"; ?>>
+ <?=htmlspecialchars($descr);?>
+ </option>
+ <?php endforeach; ?>
+ </select>
+ <br>
+ <span class="vexpl">If you selected ICMP for the protocol above, you may specify an ICMP type 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" class="vncell">Traffic Queuing / Shaping</td>
+ <td width="78%" class="vtable">
+ Direction: <select name="direction">
+ <?php if($pconfig['direction'] <> "")
+ echo "<option value=\"" . htmlspecialchars($pconfig['direction']) . "\">" . htmlspecialchars($pconfig['direction']) . "</option>";
+ ?>
+ <option value="">DONT CARE</option>
+ <option value="in">IN</option>
+ <option value="out">OUT</option>
+ </select>
+ <br> <span class="vexpl">If you need fine grained control on direction, select an option here.
+ <p> Queue: <select name="queue">
+ <?php
+ if($pconfig['queue'] <> "") echo "<option value=\"" . $pconfig['queue'] . "\">" . $pconfig['queue'] . "</option>";
+ echo "<option value=\"\"></option>";
+ if (is_array($config['pfqueueing']['queue'])) {
+ foreach ($config['pfqueueing']['queue'] as $queue) {
+ if(is_subqueue($queue['name']) == 0) {
+ echo "<option value=\"" . $queue['name'] . "\">" . $queue['name'] . "</option>";
+ }
+ }
+ }
+ ?>
+ </select><br><span class="vexpl">To enable traffic shaping on this rule, select a queue above.</span>
+ <br><span class="vexpl"><input type="checkbox" name="autocreatequeue"> Automatically create a new queue for this rule.</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/usr/local/www/firewall_shaper.php b/usr/local/www/firewall_shaper.php
new file mode 100755
index 0000000..242c3ed
--- /dev/null
+++ b/usr/local/www/firewall_shaper.php
@@ -0,0 +1,269 @@
+#!/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['pfqueueing']['rule'])) {
+ $config['pfqueueing']['rule'] = array();
+}
+if (!is_array($config['pfqueueing']['pipe'])) {
+ $config['pfqueueing']['pipe'] = array();
+}
+if (!is_array($config['pfqueueing']['queue'])) {
+ $config['pfqueueing']['queue'] = array();
+}
+$a_shaper = &$config['pfqueueing']['rule'];
+$a_pipe = &$config['pfqueueing']['pipe'];
+$a_queue = &$config['pfqueueing']['queue'];
+
+$pconfig['enable'] = isset($config['pfqueueing']['enable']);
+
+if ($_POST) {
+
+ if ($_POST['submit']) {
+ $pconfig = $_POST;
+ $config['pfqueueing']['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;
+ }
+} else if ($_GET['act'] == "toggle") {
+ if ($a_shaper[$_GET['id']]) {
+ $a_shaper[$_GET['id']]['disabled'] = !isset($a_shaper[$_GET['id']]['disabled']);
+ 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><?=gentitle("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($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>
+ <ul id="tabnav">
+ <li class="tabact">Rules</li>
+ <li class="tabinact"><a href="firewall_shaper_pipes.php">Pipes</a></li>
+ <li class="tabinact"><a href="firewall_shaper_queues.php">Queues</a></li>
+ <li class="tabinact"><a href="firewall_shaper_magic.php">Magic shaper wizard</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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
+ $dis = "";
+ if (isset($shaperent['disabled'])) {
+ $dis = "_d";
+ $textss = "<span class=\"gray\">";
+ $textse = "</span>";
+ } else {
+ $textss = $textse = "";
+ }
+ $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 $textss . htmlspecialchars($iflabels[$shaperent['interface']]);
+ echo "<br>";
+ echo "<a href=\"?act=toggle&id={$i}\">";
+ if ($shaperent['direction'] != "in")
+ echo "<img src=\"out{$dis}.gif\" width=\"11\" height=\"11\" border=\"0\" style=\"margin-top: 5px\" title=\"click to toggle enabled/disabled status\">";
+ if ($shaperent['direction'] != "out")
+ echo "<img src=\"in{$dis}.gif\" width=\"11\" height=\"11\" border=\"0\" style=\"margin-top: 5px\" title=\"click to toggle enabled/disabled status\">";
+ echo "</a>" . $textse;;
+ ?>
+ </td>
+ <td class="listr">
+ <?=$textss;?><?php if (isset($shaperent['protocol'])) echo strtoupper($shaperent['protocol']); else echo "*"; ?><?=$textse;?>
+ </td>
+ <td class="listr"><?=$textss;?><?php echo htmlspecialchars(pprint_address($shaperent['source'])); ?>
+ <?php if ($shaperent['source']['port']): ?><br>
+ Port: <?=htmlspecialchars(pprint_port($shaperent['source']['port'])); ?>
+ <?php endif; ?><?=$textse;?>
+ </td>
+ <td class="listr"><?=$textss;?><?php echo htmlspecialchars(pprint_address($shaperent['destination'])); ?>
+ <?php if ($shaperent['destination']['port']): ?><br>
+ Port: <?=htmlspecialchars(pprint_port($shaperent['destination']['port'])); ?>
+ <?php endif; ?><?=$textse;?>
+ </td>
+ <td class="listr"><?=$textss;?>
+ <?php
+ if (isset($shaperent['targetpipe'])) {
+ if ($a_pipe[$shaperent['targetpipe']]['descr'])
+ $desc = htmlspecialchars($a_pipe[$shaperent['targetpipe']]['descr']);
+ else
+ $desc = "Pipe " . ($shaperent['targetpipe']+1);
+ echo "<a href=\"firewall_shaper_pipes_edit.php?id={$shaperent['targetpipe']}\">{$desc}</a>";
+ } else if (isset($shaperent['targetqueue'])) {
+ if ($a_queue[$shaperent['targetqueue']]['descr'])
+ $desc = htmlspecialchars($a_queue[$shaperent['targetqueue']]['descr']);
+ else
+ $desc = "Queue " . ($shaperent['targetqueue']+1);
+ echo "<a href=\"firewall_shaper_queues_edit.php?id={$shaperent['targetqueue']}\">{$desc}</a>";
+ }
+ ?><?=$textse;?>
+ </td>
+ <td class="listbg">
+ <?=$textss;?><?=htmlspecialchars($shaperent['descr']);?><?=$textse;?>
+ &nbsp; </td>
+ <td valign="middle" nowrap class="list"> <a href="firewall_shaper_edit.php?id=<?=$i;?>"><img src="e.gif" title="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" title="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" title="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" title="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" title="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>
+ <td width="14"></td>
+ <td width="16"><img src="out.gif" width="11" height="11"></td>
+ <td>outgoing (as seen by firewall)</td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td><img src="in_d.gif" width="11" height="11"></td>
+ <td>incoming (disabled)</td>
+ <td width="14"></td>
+ <td><img src="out_d.gif" width="11" height="11"></td>
+ <td>outgoing (disabled)</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>
+ </tr>
+</table>
+ </form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/firewall_shaper_edit.php b/usr/local/www/firewall_shaper_edit.php
new file mode 100755
index 0000000..5b0e249
--- /dev/null
+++ b/usr/local/www/firewall_shaper_edit.php
@@ -0,0 +1,776 @@
+#!/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['iptos'] = $a_shaper[$id]['iptos'];
+ $pconfig['iplen'] = $a_shaper[$id]['iplen'];
+ $pconfig['tcpflags'] = $a_shaper[$id]['tcpflags'];
+ $pconfig['descr'] = $a_shaper[$id]['descr'];
+ $pconfig['disabled'] = isset($a_shaper[$id]['disabled']);
+
+ 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'] != "any")) {
+ $_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;
+ }
+
+ $intos = array();
+ foreach ($iptos as $tos) {
+ if ($_POST['iptos_' . $tos] == "on")
+ $intos[] = $tos;
+ else if ($_POST['iptos_' . $tos] == "off")
+ $intos[] = "!" . $tos;
+ }
+ $_POST['iptos'] = join(",", $intos);
+
+ $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['iptos'] = $_POST['iptos'];
+ $shaperent['tcpflags'] = $_POST['tcpflags'];
+ $shaperent['descr'] = $_POST['descr'];
+ $shaperent['disabled'] = $_POST['disabled'] ? true : false;
+
+ 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><?=gentitle("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 < 2 || document.iform.proto.selectedIndex == 8) {
+ 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 (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 valign="top" class="vncellreq">Disabled</td>
+ <td 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('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 IGMP 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 Type of Service (TOS)</td>
+ <td width="78%" class="vtable"> <table border="0" cellspacing="0" cellpadding="0">
+ <?php
+ $iniptos = explode(",", $pconfig['iptos']);
+ foreach ($iptos as $tos): $dontcare = true; ?>
+ <tr>
+ <td width="80" nowrap><strong>
+ <?echo $tos;?>
+ </strong></td>
+ <td nowrap> <input type="radio" name="iptos_<?=$tos;?>" value="on" <?php if (array_search($tos, $iniptos) !== false) { echo "checked"; $dontcare = false; }?>>
+ yes&nbsp;&nbsp;&nbsp;</td>
+ <td nowrap> <input type="radio" name="iptos_<?=$tos;?>" value="off" <?php if (array_search("!" . $tos, $iniptos) !== false) { echo "checked"; $dontcare = false; }?>>
+ no&nbsp;&nbsp;&nbsp;</td>
+ <td nowrap> <input type="radio" name="iptos_<?=$tos;?>" value="" <?php if ($dontcare) echo "checked";?>>
+ don't care</td>
+ </tr>
+ <?php endforeach; ?>
+ </table>
+ <span class="vexpl">Use this to match packets according to their IP TOS values.
+ </span></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/usr/local/www/firewall_shaper_queues.php b/usr/local/www/firewall_shaper_queues.php
new file mode 100755
index 0000000..fa60240
--- /dev/null
+++ b/usr/local/www/firewall_shaper_queues.php
@@ -0,0 +1,141 @@
+#!/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['pfqueueing']['pipe'])) {
+ $config['pfqueueing']['pipe'] = array();
+}
+if (!is_array($config['pfqueueing']['queue'])) {
+ $config['pfqueueing']['queue'] = array();
+}
+$a_queues = &$config['pfqueueing']['queue'];
+$a_pipe = &$config['pfqueueing']['pipe'];
+
+if ($_GET['act'] == "del") {
+ if ($a_queues[$_GET['id']]) {
+ /* check that no rule references this queue */
+ if (is_array($config['pfqueueing']['rule'])) {
+ foreach ($config['pfqueueing']['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['pfqueueing']['rule'])) {
+ for ($i = 0; isset($config['pfqueueing']['rule'][$i]); $i++) {
+ $currule = &$config['pfqueueing']['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><?=gentitle("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 Queues</p>
+<form action="firewall_shaper.php" method="post">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="firewall_rules.php">Rules</a></li>
+ <li class="tabact">Queues</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="10%" class="listhdrr">No.</td>
+ <td width="5%" class="listhdrr">Priority</td>
+ <td width="20%" class="listhdrr">Options</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">
+ <?=$queue['priority'];?></td>
+ <td class="listr">
+ <?php if ($queue['options']): ?>
+ <?=$queue['options'];?>
+ <?php endif; ?>
+ &nbsp; </td>
+ <td class="listbg">
+ <?=htmlspecialchars($queue['name']);?>
+ &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/usr/local/www/firewall_shaper_queues_edit.php b/usr/local/www/firewall_shaper_queues_edit.php
new file mode 100755
index 0000000..15e0920
--- /dev/null
+++ b/usr/local/www/firewall_shaper_queues_edit.php
@@ -0,0 +1,187 @@
+#!/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['pfqueueing']['queue'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_queues[$id]) {
+ $pconfig['bandwidth'] = $a_queues[$id]['bandwidth'] . $a_queues[$id]['bandwidthtype'];
+ $pconfig['priority'] = $a_queues[$id]['priority'];
+ $pconfig['mask'] = $a_queues[$id]['mask'];
+ $pconfig['name'] = $a_queues[$id]['name'];
+ $pconfig['options'] = $a_queues[$id]['options'];
+ $pconfig['bandwidth'] = $a_queues[$id]['bandwidth'];
+ $pconfig['bandwidthtype'] = $a_queues[$id]['bandwidthtype'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "priority");
+ $reqdfieldsn = explode(",", "Priority");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ($_POST['priority'] && (!is_numericint($_POST['priority'])
+ || ($_POST['priority'] < 1) || ($_POST['priority'] > 100))) {
+ $input_errors[] = "The priority must be an integer between 1 and 100.";
+ }
+
+ if (!$input_errors) {
+ $queue = array();
+
+ $queue['schedulertype'] = $_POST['scheduler'];
+ $queue['bandwidth'] = $_POST['bandwidth'];
+ $queue['priority'] = $_POST['priority'];
+ $queue['name'] = $_POST['name'];
+
+ $scheduleroptions="";
+ if($_POST['red'] == "on")
+ $scheduleroptions .= "red ";
+
+ if($_POST['ecn'] == "on")
+ $scheduleroptions .= "ecn ";
+
+ if($_POST['default'] == "on")
+ $scheduleroptions .= "default";
+
+ $queue['options'] = $scheduleroptions;
+
+ 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><?=gentitle("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); ?>
+ <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">Bandwidth</td>
+ <td class="vtable"> <input name="bandwidth" class="formfld" value="<?=htmlspecialchars($pconfig['bandwidth']);?>">
+ <select name="bandwidthtype">
+ <option value="<?=htmlspecialchars($pconfig['bandwidthtype']);?>"><?=htmlspecialchars($pconfig['bandwidthtype']);?></option>
+ <option value="b">bit/s</option>
+ <option value="Kb">Kilobit/s</option>
+ <option value="Mb">Megabit/s</option>
+ <option value="Gb">Gigabit/s</option>
+ </select>
+ <br>
+ <span class="vexpl">Choose the amount of bandwidth for this queue
+ </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Priority</td>
+ <td width="78%" class="vtable"> <input name="priority" type="text" id="priority" size="5" value="<?=htmlspecialchars($pconfig['priority']);?>">
+ <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 prioritys (higher priority = higher share of bandwidth).
+ Note that prioritys are not priorities; a queue with a lower
+ priority is still guaranteed to get its fraction of the bandwidth
+ even if a queue with a higher priority is permanently backlogged.
+ </span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Name</td>
+ <td width="78%" class="vtable"> <input name="name" type="text" class="formfld" id="name" size="40" value="<?=htmlspecialchars($pconfig['name']);?>">
+ <br> <span class="vexpl">Enter the name of the queue here. Do not use spaces!
+ </span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Scheduler </td>
+ <td width="78%" class="vtable">
+ <select name="scheduler">
+ <option value="priq">Priority based queueing</option>
+ <option value="cbq">Class based queueing</option>
+ <option value="hfsc">Hierarchical Fair Service Curve queueing</option>
+ </select>
+ <br> <span class="vexpl">Select which type of queueing you would like to use
+ </span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Scheduler options</td>
+ <td width="78%" class="vtable">
+ <?php
+ $red = strpos($pconfig['options'], "red");
+ $ecn = strpos($pconfig['options'], "ecn");
+ $default = strpos($pconfig['options'], "default");
+ ?>
+ <input type=checkbox name="red" <?php if($red) echo " CHECKED";?> > Random Early Detection<br>
+ <input type=checkbox name="ecn" <?php if($ecn) echo " CHECKED";?> > Explicit Congestion Notification<br>
+ <input type=checkbox name="default" <?php if($default) echo " CHECKED";?> > Default (Clasee based queueing only)<br>
+ <br> <span class="vexpl">Select options for this queue
+ </span></td>
+ </tr>
+
+ <!-- XXX: add javascript to show/hide queueing options such as low bandwidth (hfsc, cbq) -->
+
+ <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 include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/graph.php b/usr/local/www/graph.php
new file mode 100755
index 0000000..7fac8f3
--- /dev/null
+++ b/usr/local/www/graph.php
@@ -0,0 +1,325 @@
+#!/usr/local/bin/php -f
+<?php
+/*
+ graph.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004 T. Lechat <dev@lechat.org> 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.
+*/
+
+// VERSION 1.0.4
+
+/********** HTTP GET Based Conf ***********/
+$ifnum=@$_GET["ifnum"]; //BSD / SNMP interface name / number
+$ifname=@$_GET["ifname"]?$_GET["ifname"]:"Interface $ifnum"; //Interface name that will be showed on top right of graph
+
+/********* Other conf *******/
+$scale_type="up"; //Autoscale default setup : "up" = only increase scale; "follow" = increase and decrease scale according to current graphed datas
+$nb_plot=120; //NB plot in graph
+$time_interval=1; //Refresh time Interval
+$first_stage_time_interval=2; //First stage time Intervall
+
+$urldata=@$_SERVER["SCRIPT_NAME"];
+$fetch_link = "ifstats.cgi?$ifnum";
+
+//Style
+$style['bg']="fill:white;stroke:none;stroke-width:0;opacity:1;";
+$style['axis']="fill:black;stroke:black;stroke-width:1;";
+$style['in']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
+$style['out']="fill:#8092B3; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:7;";
+$style['graph_in']="fill:none;stroke:#435370;stroke-width:1;opacity:0.8;";
+$style['graph_out']="fill:none;stroke:#8092B3;stroke-width:1;opacity:0.8;";
+$style['legend']="fill:black; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
+$style['graphname']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:8;";
+$style['grid_txt']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:6;";
+$style['grid']="stroke:gray;stroke-width:1;opacity:0.5;";
+$style['switch_unit']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
+$style['switch_scale']="fill:#435370; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4; text-decoration:underline;";
+$style['error']="fill:blue; font-family:Arial; font-size:4;";
+$style['collect_initial']="fill:gray; font-family:Tahoma, Verdana, Arial, Helvetica, sans-serif; font-size:4;";
+
+//Error text if we cannot fetch data : depends on which method is used
+$error_text = "Cannot get data about interface $ifnum";
+
+$height=100; //SVG internal height : do not modify
+$width=200; //SVG internal width : do not modify
+
+/********* Graph DATA **************/
+header("Content-type: image/svg+xml");
+print('<?xml version="1.0" encoding="iso-8859-1"?>' . "\n");?><svg width="100%" height="100%" viewBox="0 0 <?=$width?> <?=$height?>" preserveAspectRatio="none" xml:space="preserve" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" onload="init(evt)">
+<g id="graph" style="visibility:visible">
+ <rect id="bg" x1="0" y1="0" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['bg']?>"/>
+ <line id="axis_x" x1="0" y1="0" x2="0" y2="<?=$height?>" style="<?=$style['axis']?>"/>
+ <line id="axis_y" x1="0" y1="<?=$height?>" x2="<?=$width?>" y2="<?=$height?>" style="<?=$style['axis']?>"/>
+ <path id="graph_out" d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_out']?>"/>
+ <path id="graph_in" d="M0 <?=$height?> L 0 <?=$height?>" style="<?=$style['graph_in']?>"/>
+ <path id="grid" d="M0 <?=$height/4*1?> L <?=$width?> <?=$height/4*1?> M0 <?=$height/4*2?> L <?=$width?> <?=$height/4*2?> M0 <?=$height/4*3?> L <?=$width?> <?=$height/4*3?>" style="<?=$style[grid]?>"/>
+ <text id="grid_txt1" x="<?=$width?>" y="<?=$height/4*1?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
+ <text id="grid_txt2" x="<?=$width?>" y="<?=$height/4*2?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
+ <text id="grid_txt3" x="<?=$width?>" y="<?=$height/4*3?>" style="<?=$style['grid_txt']?> text-anchor:end"> </text>
+ <text id="graph_in_lbl" x="5" y="8" style="<?=$style['in']?>">In</text>
+ <text id="graph_out_lbl" x="5" y="16" style="<?=$style['out']?> ">Out</text>
+ <text id="graph_in_txt" x="20" y="8" style="<?=$style['in']?>"> </text>
+ <text id="graph_out_txt" x="20" y="16" style="<?=$style['out']?> "> </text>
+ <text id="ifname" x="<?=$width?>" y="8" style="<?=$style['graphname']?> text-anchor:end"><?=$ifname?></text>
+ <text id="switch_unit" x="<?=$width*0.55?>" y="5" style="<?=$style['switch_unit']?>">Switch to bytes/s</text>
+ <text id="switch_scale" x="<?=$width*0.55?>" y="11" style="<?=$style['switch_scale']?>">AutoScale (<?=$scale_type?>)</text>
+ <text id="datetime" x="<?=$width*0.33?>" y="5" style="<?=$style['legend']?>"> </text>
+ <text id="graphlast" x="<?=$width*0.55?>" y="17" style="<?=$style['legend']?>">Graph shows last <?=$time_interval*$nb_plot?> seconds</text>
+ <polygon id="axis_arrow_x" style="<?=$style['axis']?>" points="<?=($width) . "," . ($height)?> <?=($width-2) . "," . ($height-2)?> <?=($width-2) . "," . $height?>"/>
+ <text id="error" x="<?=$width*0.5?>" y="<?=$height*0.5?>" style="visibility:hidden;<?=$style['error']?> text-anchor:middle"><?=$error_text?></text>
+ <text id="collect_initial" x="<?=$width*0.5?>" y="<?=$height*0.5?>" style="visibility:hidden;<?=$style['collect_initial']?> text-anchor:middle">Collecting initial data, please wait...</text>
+</g>
+
+<script type="text/ecmascript"><![CDATA[
+var SVGDoc;
+var last_ifin=0;
+var last_ifout=0;
+var last_ugmt=0;
+var diff_ugmt=0;
+var diff_ifin=0;
+var diff_ifout=0;
+var max = 0;
+plot_in=new Array();
+plot_out=new Array();
+
+var isfirst=1;
+var index_plot=0;
+var step = <?=$width?> / <?=$nb_plot?> ;
+var unit = 'bits';
+var scale_type = '<?=$scale_type?>';
+
+function init(evt) {
+ SVGDoc = evt.getTarget().getOwnerDocument();
+ SVGDoc.getElementById("switch_unit").addEventListener("mousedown", switch_unit, false);
+ SVGDoc.getElementById("switch_scale").addEventListener("mousedown", switch_scale, false);
+
+ go();
+}
+
+function switch_unit(event)
+{
+ SVGDoc.getElementById('switch_unit').getFirstChild().setData('Switch to ' + unit + '/s');
+ if(unit=='bits') unit='bytes';else unit='bits';
+}
+
+function switch_scale(event)
+{
+ if(scale_type=='up') scale_type='follow';else scale_type='up';
+ SVGDoc.getElementById('switch_scale').getFirstChild().setData('AutoScale (' + scale_type + ')');
+}
+
+function go() {
+ getURL('<?=$fetch_link?>',urlcallback);
+}
+
+function urlcallback(obj) {
+ var error = 0;
+ now = new Date();
+
+ //Show datetimelegend
+ var datetime = (now.getMonth()+1) + "/" + now.getDate() + "/" + now.getFullYear() + ' ' +
+ LZ(now.getHours()) + ":" + LZ(now.getMinutes()) + ":" + LZ(now.getSeconds());
+ SVGDoc.getElementById('datetime').getFirstChild().setData(datetime);
+
+ //shift plot to left if nb_plot is already completed
+ var i=0;
+ if(index_plot > <?=$nb_plot?>)
+ {
+ while (i <= <?=$nb_plot?>)
+ {
+ var a=i+1;
+ plot_in[i]=plot_in[a];
+ plot_out[i]=plot_out[a];
+ i=i+1;
+ }
+ index_plot = <?=$nb_plot?>;
+ plot_in[index_plot]=0;
+ plot_out[index_plot]=0;
+ }
+
+ //if Geturl returns something
+ if (obj.success){
+ var t=obj.content.split("|");
+ var ugmt = parseFloat(t[0]);//ugmt is an unixtimestamp style
+ var ifin = parseInt(t[1]);//ifin must be in bytes
+ var ifout = parseInt(t[2]);//ifout must be in bytes
+ var scale;
+
+ if(!isNumber(ifin) || !isNumber(ifout)) {
+ goerror();
+ return;
+ } else {
+ SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'hidden');
+ }
+
+ diff_ugmt = ugmt - last_ugmt;
+ diff_ifin = ifin - last_ifin;
+ diff_ifout = ifout - last_ifout;
+
+ if (diff_ugmt == 0)
+ diff_ugmt = 1; /* avoid division by zero */
+
+ last_ugmt = ugmt;
+ last_ifin = ifin;
+ last_ifout = ifout;
+
+ if(isfirst) {
+ SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'visible');
+ setTimeout('go()',<?=1000*$first_stage_time_interval?>);
+ isfirst=0;
+ return;
+ } else SVGDoc.getElementById("collect_initial").getStyle().setProperty ('visibility', 'hidden');
+
+ plot_in[index_plot] = diff_ifin / diff_ugmt;
+ plot_out[index_plot]= diff_ifout / diff_ugmt;
+
+ SVGDoc.getElementById('graph_in_txt').getFirstChild().setData(formatSpeed(plot_in[index_plot],unit));
+ SVGDoc.getElementById('graph_out_txt').getFirstChild().setData(formatSpeed(plot_out[index_plot],unit));
+
+ /* determine peak for sensible scaling */
+ if (scale_type == 'up') {
+ if (plot_in[index_plot] > max)
+ max = plot_in[index_plot];
+ if (plot_out[index_plot] > max)
+ max = plot_out[index_plot];
+ } else if (scale_type == 'follow') {
+ i = 0;
+ max = 0;
+ while (i <= <?=$nb_plot?>) {
+ if (plot_in[i] > max)
+ max = plot_in[i];
+ if (plot_out[i] > max)
+ max = plot_out[i];
+ i++;
+ }
+ }
+
+ var rmax;
+
+ if (unit == 'bits') {
+ /* round up max, such that
+ 100 kbps -> 200 kbps -> 400 kbps -> 800 kbps -> 1 Mbps -> 2 Mbps -> ... */
+ rmax = 12500;
+ i = 0;
+ while (max > rmax) {
+ i++;
+ if (i && (i % 4 == 0))
+ rmax *= 1.25;
+ else
+ rmax *= 2;
+ }
+ } else {
+ /* round up max, such that
+ 10 KB/s -> 20 KB/s -> 40 KB/s -> 80 KB/s -> 100 KB/s -> 200 KB/s -> 400 KB/s -> 800 KB/s -> 1 MB/s ... */
+ rmax = 10240;
+ i = 0;
+ while (max > rmax) {
+ i++;
+ if (i && (i % 4 == 0))
+ rmax *= 1.25;
+ else
+ rmax *= 2;
+
+ if (i == 8)
+ rmax *= 1.024;
+ }
+ }
+
+ scale = <?=$height?> / rmax;
+
+ /* change labels accordingly */
+ SVGDoc.getElementById('grid_txt1').getFirstChild().setData(formatSpeed(3*rmax/4,unit));
+ SVGDoc.getElementById('grid_txt2').getFirstChild().setData(formatSpeed(2*rmax/4,unit));
+ SVGDoc.getElementById('grid_txt3').getFirstChild().setData(formatSpeed(rmax/4,unit));
+
+ i = 0;
+
+ while (i <= index_plot)
+ {
+ var x = step * i;
+ var y_in= <?=$height?> - (plot_in[i] * scale);
+ var y_out= <?=$height?> - (plot_out[i] * scale);
+ if(i==0) {
+ var path_in = "M" + x + " " + y_in;
+ var path_out = "M" + x + " " + y_out;
+ }
+ else
+ {
+ var path_in = path_in + " L" + x + " " + y_in;
+ var path_out = path_out + " L" + x + " " + y_out;
+ }
+ i = i + 1;
+ }
+
+ index_plot = index_plot+1;
+ SVGDoc.getElementById('graph_in').setAttribute("d", path_in);
+ SVGDoc.getElementById('graph_out').setAttribute("d", path_out);
+
+ setTimeout('go()',<?=1000*$time_interval?>);
+ }
+ else
+ { //In case of Geturl fails
+ goerror();
+ }
+}
+
+function goerror() {
+ SVGDoc.getElementById("error").getStyle().setProperty ('visibility', 'visible');
+ setTimeout('go()',<?=1000*$time_interval?>);
+}
+
+function isNumber(a) {
+ return typeof a == 'number' && isFinite(a);
+}
+
+function formatSpeed(speed,unit){
+ if(unit=='bits') return formatSpeedBits(speed);
+ else if(unit=='bytes') return formatSpeedBytes(speed);
+}
+
+function formatSpeedBits(speed) {
+ // format speed in bits/sec, input: bytes/sec
+ if (speed < 125000)
+ return Math.round(speed / 125) + " Kbps";
+ else if (speed < 125000000)
+ return Math.round(speed / 1250)/100 + " Mbps";
+ else
+ return Math.round(speed / 1250000)/100 + " Gbps"; /* wow! */
+}
+function formatSpeedBytes(speed) {
+ // format speed in bytes/sec, input: bytes/sec
+ if (speed < 1048576)
+ return Math.round(speed / 10.24)/100 + " KB/s";
+ else if (speed < 1073741824)
+ return Math.round(speed / 10485.76)/100 + " MB/s";
+ else
+ return Math.round(speed / 10737418.24)/100 + " GB/s"; /* wow! */
+}
+function LZ(x) {
+ return (x < 0 || x > 9 ? "" : "0") + x
+}
+]]></script>
+</svg> \ No newline at end of file
diff --git a/usr/local/www/gui.css b/usr/local/www/gui.css
new file mode 100755
index 0000000..3a31c09
--- /dev/null
+++ b/usr/local/www/gui.css
@@ -0,0 +1,271 @@
+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;
+}
+.hostname {
+ 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;
+}
+ul#tabnav {
+ font-size: 11px;
+ font-weight: bold;
+ list-style-type: none;
+ margin: 0;
+ padding: 0;
+}
+ul#tabnav li.tabinact {
+ float: left;
+ border-left: 1px solid #999999;
+ background-color: #777777;
+ color: #FFFFFF;
+ padding: 0;
+ white-space: nowrap;
+}
+ul#tabnav li.tabinact a {
+ float: left;
+ display: block;
+ text-decoration: none;
+ padding: 5px 8px 5px 8px;
+ color: #FFFFFF;
+}
+ul#tabnav li.tabact {
+ float: left;
+ background-color: #EEEEEE;
+ color: #000000;
+ padding: 5px 8px 5px 8px;
+ white-space: nowrap;
+}
+.tabcont {
+ background-color: #EEEEEE;
+ padding-right: 12px;
+ padding-left: 12px;
+ padding-top: 12px;
+ padding-bottom: 12px;
+}
diff --git a/usr/local/www/guiconfig.inc b/usr/local/www/guiconfig.inc
new file mode 100755
index 0000000..8efccfb
--- /dev/null
+++ b/usr/local/www/guiconfig.inc
@@ -0,0 +1,442 @@
+<?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");
+}
+
+/* parse the configuration and include all configuration functions */
+require_once("config.inc");
+require_once("functions.inc");
+
+$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";
+$d_passthrumacsdirty_path = $g['varrun_path'] . "/passthrumacs.dirty";
+$d_allowedipsdirty_path = $g['varrun_path'] . "/allowedips.dirty";
+$d_ovpnclidirty_path = $g['varrun_path'] . "/ovpnclient.dirty";
+
+if (file_exists($d_firmwarelock_path)) {
+ if (!$d_isfwfile) {
+ header("Location: system_firmware.php");
+ exit;
+ } else {
+ return;
+ }
+}
+
+/* some well knows ports */
+$wkports = array(21 => "FTP", 22 => "SSH", 23 => "Telnet", 25 => "SMTP", 53 => "DNS", 80 => "HTTP",
+ 110 => "POP3", 143 => "IMAP", 443 => "HTTPS");
+
+$iptos = array("lowdelay", "throughput", "reliability", "mincost", "congestion");
+/* 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',
+ 'user_fqdn' => 'User FQDN');
+
+$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('sha1' => 'SHA1', 'md5' => 'MD5');
+$p2_halgos = array('hmac_sha1' => 'SHA1', 'hmac_md5' => 'MD5');
+$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) {
+
+ /* check for bad control characters */
+ foreach ($postdata as $pn => $pd) {
+ if (is_string($pd) && preg_match("/[\\x00-\\x08\\x0b\\x0c\\x0e-\\x1f]/", $pd)) {
+ $input_errors[] = "The field '" . $pn . "' contains invalid characters.";
+ }
+ }
+
+ 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 <a href=\"/reboot.php\">reboot</a> 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 passthrumacs_sort() {
+ global $g, $config;
+
+ function passthrumacscmp($a, $b) {
+ return strcmp($a['mac'], $b['mac']);
+ }
+
+ usort($config['captiveportal']['passthrumac'],"passthrumacscmp");
+}
+
+function allowedips_sort() {
+ global $g, $config;
+
+ function allowedipscmp($a, $b) {
+ return strcmp($a['ip'], $b['ip']);
+ }
+
+ usort($config['captiveportal']['allowedip'],"allowedipscmp");
+}
+
+function wol_sort() {
+ global $g, $config;
+
+ function wolcmp($a, $b) {
+ return strcmp($a['descr'], $b['descr']);
+ }
+
+ usort($config['wol']['wolentry'], "wolcmp");
+}
+
+function gentitle($pgname) {
+ global $config;
+ return $config['system']['hostname'] . "." . $config['system']['domain'] . " - " . $pgname;
+}
+
+?>
diff --git a/usr/local/www/ifstats.cgi b/usr/local/www/ifstats.cgi
new file mode 100755
index 0000000..944e95e
--- /dev/null
+++ b/usr/local/www/ifstats.cgi
Binary files differ
diff --git a/usr/local/www/index.php b/usr/local/www/index.php
new file mode 100755
index 0000000..ecaef0c
--- /dev/null
+++ b/usr/local/www/index.php
@@ -0,0 +1,180 @@
+#!/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) */
+unset($hwcrypto);
+$fd = @fopen("{$g['varlog_path']}/dmesg.boot", "r");
+if ($fd) {
+ while (!feof($fd)) {
+ $dmesgl = fgets($fd);
+ if (preg_match("/^hifn.: (.*?),/", $dmesgl, $matches)) {
+ $hwcrypto = $matches[1];
+ break;
+ }
+ }
+ fclose($fd);
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("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("/sbin/sysctl -n kern.boottime", $boottime);
+ preg_match("/sec = (\d+)/", $boottime[0], $matches);
+ $boottime = $matches[1];
+ $uptime = time() - $boottime;
+
+ if ($uptime > 60)
+ $uptime += 30;
+ $updays = (int)($uptime / 86400);
+ $uptime %= 86400;
+ $uphours = (int)($uptime / 3600);
+ $uptime %= 3600;
+ $upmins = (int)($uptime / 60);
+
+ $uptimestr = "";
+ if ($updays > 1)
+ $uptimestr .= "$updays days, ";
+ else if ($updays > 0)
+ $uptimestr .= "1 day, ";
+ $uptimestr .= sprintf("%02d:%02d", $uphours, $upmins);
+ echo htmlspecialchars($uptimestr);
+ ?>
+ </td>
+ </tr><?php if ($config['lastchange']): ?>
+ <tr>
+ <td width="25%" class="vncellt">Last config change</td>
+ <td width="75%" class="listr">
+ <?=htmlspecialchars(date("D M j G:i:s T Y", $config['lastchange']));?>
+ </td>
+ </tr><?php endif; ?>
+ <tr>
+ <td width="25%" class="vncellt">CPU usage</td>
+ <td width="75%" class="listr">
+<?php
+$cpuTicks = explode(" ", `/sbin/sysctl -n kern.cp_time`);
+sleep(1);
+$cpuTicks2 = explode(" ", `/sbin/sysctl -n kern.cp_time`);
+
+$diff = array();
+$diff['user'] = $cpuTicks2[0] - $cpuTicks[0];
+$diff['nice'] = $cpuTicks2[1] - $cpuTicks[1];
+$diff['sys'] = $cpuTicks2[2] - $cpuTicks[2];
+$diff['intr'] = $cpuTicks2[3] - $cpuTicks[3];
+$diff['idle'] = $cpuTicks2[4] - $cpuTicks[4];
+
+$totalDiff = $diff['user'] + $diff['nice'] + $diff['sys'] + $diff['intr'] + $diff['idle'];
+
+$cpuUsage = round(100 * (1 - $diff['idle'] / $totalDiff), 0);
+
+echo "<img src='bar_left.gif' height='15' width='4' border='0' align='absmiddle'>";
+echo "<img src='bar_blue.gif' height='15' width='" . $cpuUsage . "' border='0' align='absmiddle'>";
+echo "<img src='bar_gray.gif' height='15' width='" . (100 - $cpuUsage) . "' border='0' align='absmiddle'>";
+echo "<img src='bar_right.gif' height='15' width='5' border='0' align='absmiddle'> ";
+echo $cpuUsage . "%";
+?>
+ </td>
+ </tr>
+ <tr>
+ <td width="25%" class="vncellt">Memory usage</td>
+ <td width="75%" class="listr">
+<?php
+
+exec("/sbin/sysctl -n vm.stats.vm.v_active_count vm.stats.vm.v_inactive_count " .
+ "vm.stats.vm.v_wire_count vm.stats.vm.v_cache_count vm.stats.vm.v_free_count", $memory);
+
+$totalMem = $memory[0] + $memory[1] + $memory[2] + $memory[3] + $memory[4];
+$freeMem = $memory[4];
+$usedMem = $totalMem - $freeMem;
+$memUsage = round(($usedMem * 100) / $totalMem, 0);
+
+echo " <img src='bar_left.gif' height='15' width='4' border='0' align='absmiddle'>";
+echo "<img src='bar_blue.gif' height='15' width='" . $memUsage . "' border='0' align='absmiddle'>";
+echo "<img src='bar_gray.gif' height='15' width='" . (100 - $memUsage) . "' border='0' align='absmiddle'>";
+echo "<img src='bar_right.gif' height='15' width='5' border='0' align='absmiddle'> ";
+echo $memUsage . "%";
+?>
+ </td>
+ </tr>
+ </table>
+ <?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php
new file mode 100755
index 0000000..b4cc30b
--- /dev/null
+++ b/usr/local/www/interfaces.php
@@ -0,0 +1,630 @@
+#!/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['pppoe_dialondemand'] = $config['pppoe']['ondemand'];
+$pconfig['pppoe_idletimeout'] = $config['pppoe']['timeout'];
+
+$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['pptp_dialondemand'] = $config['pptp']['ondemand'];
+$pconfig['pptp_idletimeout'] = $config['pptp']['timeout'];
+
+$pconfig['bigpond_username'] = $config['bigpond']['username'];
+$pconfig['bigpond_password'] = $config['bigpond']['password'];
+$pconfig['bigpond_authserver'] = $config['bigpond']['authserver'];
+$pconfig['bigpond_authdomain'] = $config['bigpond']['authdomain'];
+$pconfig['bigpond_minheartbeatinterval'] = $config['bigpond']['minheartbeatinterval'];
+
+$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 if ($wancfg['ipaddr'] == "bigpond") {
+ $pconfig['type'] = "BigPond";
+} 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") {
+ if ($_POST['pppoe_dialondemand']) {
+ $reqdfields = explode(" ", "username password pppoe_dialondemand pppoe_idletimeout");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password,Dial on demand,Idle timeout value");
+ } else {
+ $reqdfields = explode(" ", "username password");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password");
+ }
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "PPTP") {
+ if ($_POST['pptp_dialondemand']) {
+ $reqdfields = explode(" ", "pptp_username pptp_password pptp_local pptp_subnet pptp_remote pptp_dialondemand pptp_idletimeout");
+ $reqdfieldsn = explode(",", "PPTP username,PPTP password,PPTP local IP address,PPTP subnet,PPTP remote IP address,Dial on demand,Idle timeout value");
+ } else {
+ $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);
+ } else if ($_POST['type'] == "BigPond") {
+ $reqdfields = explode(" ", "bigpond_username bigpond_password");
+ $reqdfieldsn = explode(",", "BigPond username,BigPond password");
+ 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['pppoe_idletimeout'] && !is_numericint($_POST['pppoe_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ 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['pptp_idletimeout'] && !is_numericint($_POST['pptp_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ if (($_POST['bigpond_authserver'] && !is_domain($_POST['bigpond_authserver']))) {
+ $input_errors[] = "The authentication server name contains invalid characters.";
+ }
+ if (($_POST['bigpond_authdomain'] && !is_domain($_POST['bigpond_authdomain']))) {
+ $input_errors[] = "The authentication domain name contains invalid characters.";
+ }
+ if ($_POST['bigpond_minheartbeatinterval'] && !is_numericint($_POST['bigpond_minheartbeatinterval'])) {
+ $input_errors[] = "The minimum heartbeat interval must be an integer.";
+ }
+ 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['pppoe']['ondemand']);
+ unset($config['pppoe']['timeout']);
+ unset($config['pptp']['username']);
+ unset($config['pptp']['password']);
+ unset($config['pptp']['local']);
+ unset($config['pptp']['subnet']);
+ unset($config['pptp']['remote']);
+ unset($config['pptp']['ondemand']);
+ unset($config['pptp']['timeout']);
+ unset($config['bigpond']['username']);
+ unset($config['bigpond']['password']);
+ unset($config['bigpond']['authserver']);
+ unset($config['bigpond']['authdomain']);
+ unset($config['bigpond']['minheartbeatinterval']);
+
+ 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'];
+ $config['pppoe']['ondemand'] = $_POST['pppoe_dialondemand'];
+ $config['pppoe']['timeout'] = $_POST['pppoe_idletimeout'];
+ } 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'];
+ $config['pptp']['ondemand'] = $_POST['pptp_dialondemand'];
+ $config['pptp']['timeout'] = $_POST['pptp_idletimeout'];
+ } else if ($_POST['type'] == "BigPond") {
+ $wancfg['ipaddr'] = "bigpond";
+ $config['bigpond']['username'] = $_POST['bigpond_username'];
+ $config['bigpond']['password'] = $_POST['bigpond_password'];
+ $config['bigpond']['authserver'] = $_POST['bigpond_authserver'];
+ $config['bigpond']['authdomain'] = $_POST['bigpond_authdomain'];
+ $config['bigpond']['minheartbeatinterval'] = $_POST['bigpond_minheartbeatinterval'];
+ }
+
+ $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><?=gentitle("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 enable_change(enable_change) {
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.disabled = 1;
+ }
+}
+
+function enable_change_pptp(enable_change_pptp) {
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ document.iform.pptp_local.disabled = 0;
+ document.iform.pptp_remote.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+}
+
+function type_change(enable_change,enable_change_pptp) {
+ switch (document.iform.type.selectedIndex) {
+ case 0:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.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.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.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.pppoe_dialondemand.disabled = 0;
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.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.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 0;
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 4:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 0;
+ document.iform.bigpond_password.disabled = 0;
+ document.iform.bigpond_authserver.disabled = 0;
+ document.iform.bigpond_authdomain.disabled = 0;
+ document.iform.bigpond_minheartbeatinterval.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($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 BigPond");
+ 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 valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pppoe_dialondemand" type="checkbox" id="pppoe_dialondemand" value="enable" <?php if ($pconfig['pppoe_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pppoe_idletimeout" type="text" class="formfld" id="pppoe_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pppoe_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</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>
+ <tr>
+ <td valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pptp_dialondemand" type="checkbox" id="pptp_dialondemand" value="enable" <?php if ($pconfig['pptp_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change_pptp(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pptp_idletimeout" type="text" class="formfld" id="pptp_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pptp_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">BigPond Cable configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="bigpond_username" type="text" class="formfld" id="bigpond_username" size="20" value="<?=htmlspecialchars($pconfig['bigpond_username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="bigpond_password" type="text" class="formfld" id="bigpond_password" size="20" value="<?=htmlspecialchars($pconfig['bigpond_password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication server</td>
+ <td class="vtable"><input name="bigpond_authserver" type="text" class="formfld" id="bigpond_authserver" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authserver']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the default (&quot;dce-server&quot;) is used. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication domain</td>
+ <td class="vtable"><input name="bigpond_authdomain" type="text" class="formfld" id="bigpond_authdomain" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authdomain']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the domain name assigned via DHCP will be used.<br>
+ <br>
+ Note: the BigPond client implicitly sets the &quot;Allow DNS server list to be overridden by DHCP/PPP on WAN&quot; on the System: General setup page. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Min. heartbeat interval</td>
+ <td class="vtable">
+ <input name="bigpond_minheartbeatinterval" type="text" class="formfld" id="bigpond_minheartbeatinterval" size="8" value="<?=htmlspecialchars($pconfig['bigpond_minheartbeatinterval']);?>">
+ seconds<br>
+ Setting this to a sensible value (e.g. 60 seconds) can protect against DoS attacks. </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" onClick="enable_change_pptp(true)&&enable_change(true)">
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+type_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_assign.php b/usr/local/www/interfaces_assign.php
new file mode 100755
index 0000000..0f57d30
--- /dev/null
+++ b/usr/local/www/interfaces_assign.php
@@ -0,0 +1,265 @@
+#!/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.
+*/
+
+/* get list without VLAN interfaces */
+$portlist = get_interface_list();
+
+/* add VLAN interfaces */
+if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
+ $i = 0;
+ foreach ($config['vlans']['vlan'] as $vlan) {
+ $portlist['vlan' . $i] = $vlan;
+ $portlist['vlan' . $i]['isvlan'] = true;
+ $i++;
+ }
+}
+
+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[$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);
+ }
+}
+
+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") {
+ /* find next free optional interface number */
+ $i = 1;
+ while (is_array($config['interfaces']['opt' . $i]))
+ $i++;
+
+ $newifname = 'opt' . $i;
+ $config['interfaces'][$newifname] = array();
+ $config['interfaces'][$newifname]['descr'] = "OPT" . $i;
+
+ /* 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;
+ }
+ }
+
+ 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><?=gentitle("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 width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Interface assignments</li>
+ <li class="tabinact"><a href="interfaces_vlan.php">VLANs</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr">Interface</td>
+ <td class="listhdr">Network port</td>
+ <td class="list">&nbsp;</td>
+ </tr>
+ <?php foreach ($config['interfaces'] as $ifname => $iface):
+ if ($iface['descr'])
+ $ifdescr = $iface['descr'];
+ else
+ $ifdescr = strtoupper($ifname);
+ ?>
+ <tr>
+ <td class="listlr" valign="middle"><strong><?=$ifdescr;?></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";?>>
+ <?php if ($portinfo['isvlan']) {
+ $descr = "VLAN {$portinfo['tag']} on {$portinfo['if']}";
+ if ($portinfo['descr'])
+ $descr .= " (" . $portinfo['descr'] . ")";
+ echo htmlspecialchars($descr);
+ } else
+ echo 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" title="delete interface" width="17" height="17" border="0"></a>
+ <?php endif; ?>
+ </td>
+ </tr>
+ <?php endforeach; ?>
+ <?php if (count($config['interfaces']) < count($portlist)): ?>
+ <tr>
+ <td class="list" colspan="2"></td>
+ <td class="list" nowrap>
+ <a href="interfaces_assign.php?act=add"><img src="plus.gif" title="add interface" width="17" height="17" border="0"></a>
+ </td>
+ </tr>
+ <?php else: ?>
+ <tr>
+ <td class="list" colspan="3" height="10"></td>
+ </tr>
+ <?php endif; ?>
+</table>
+ <input name="Submit" type="submit" class="formbtn" value="Save">
+ <p><span class="vexpl"><strong><span class="red">Warning:</span><br>
+ </strong>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: </span></p>
+ <ul>
+ <li><span class="vexpl">change the IP address of your computer</span></li>
+ <li><span class="vexpl">renew its DHCP lease</span></li>
+ <li><span class="vexpl">access the webGUI with the new IP address</span></li>
+ </ul></td>
+ </tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_lan.php b/usr/local/www/interfaces_lan.php
new file mode 100755
index 0000000..66af153
--- /dev/null
+++ b/usr/local/www/interfaces_lan.php
@@ -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><?=gentitle("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 its 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/usr/local/www/interfaces_opt.php b/usr/local/www/interfaces_opt.php
new file mode 100755
index 0000000..fffc17b
--- /dev/null
+++ b/usr/local/www/interfaces_opt.php
@@ -0,0 +1,276 @@
+#!/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.";
+ }
+ /* captive portal on? */
+ if (isset($config['captiveportal']['enable'])) {
+ $input_errors[] = "Interfaces cannot be bridged while the captive portal is enabled.";
+ }
+ } 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();
+
+ /* is this the captive portal interface? */
+ if (isset($config['captiveportal']['enable']) &&
+ ($config['captiveportal']['interface'] == ('opt' . $index))) {
+ captiveportal_configure();
+ }
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("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($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/usr/local/www/interfaces_vlan.php b/usr/local/www/interfaces_vlan.php
new file mode 100755
index 0000000..f724ef3
--- /dev/null
+++ b/usr/local/www/interfaces_vlan.php
@@ -0,0 +1,149 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_vlan.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['vlans']['vlan']))
+ $config['vlans']['vlan'] = array();
+
+$a_vlans = &$config['vlans']['vlan'] ;
+
+function vlan_inuse($num) {
+ global $config, $g;
+
+ if ($config['interfaces']['lan']['if'] == "vlan{$num}")
+ return true;
+ if ($config['interfaces']['wan']['if'] == "vlan{$num}")
+ return true;
+
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if ($config['interfaces']['opt' . $i]['if'] == "vlan{$num}")
+ return true;
+ }
+
+ return false;
+}
+
+function renumber_vlan($if, $delvlan) {
+ if (!preg_match("/^vlan/", $if))
+ return $if;
+
+ $vlan = substr($if, 4);
+ if ($vlan > $delvlan)
+ return "vlan" . ($vlan - 1);
+ else
+ return $if;
+}
+
+if ($_GET['act'] == "del") {
+ /* check if still in use */
+ if (vlan_inuse($_GET['id'])) {
+ $input_errors[] = "This VLAN cannot be deleted because it is still being used as an interface.";
+ } else {
+ unset($a_vlans[$_GET['id']]);
+
+ /* renumber all interfaces that use VLANs */
+ $config['interfaces']['lan']['if'] = renumber_vlan($config['interfaces']['lan']['if'], $_GET['id']);
+ $config['interfaces']['wan']['if'] = renumber_vlan($config['interfaces']['wan']['if'], $_GET['id']);
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++)
+ $config['interfaces']['opt' . $i]['if'] = renumber_vlan($config['interfaces']['opt' . $i]['if'], $_GET['id']);
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+ header("Location: interfaces_vlan.php");
+ exit;
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Interfaces: Assign network ports: VLANs");?></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: VLANs</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)); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="interfaces_assign.php">Interface assignments</a></li>
+ <li class="tabact">VLANs</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="20%" class="listhdrr">Interface</td>
+ <td width="20%" class="listhdrr">VLAN tag</td>
+ <td width="50%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_vlans as $vlan): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($vlan['if']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($vlan['tag']);?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($vlan['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="interfaces_vlan_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="interfaces_vlan.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this VLAN?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="3">&nbsp;</td>
+ <td class="list"> <a href="interfaces_vlan_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <tr>
+ <td colspan="3" class="list"><p class="vexpl"><span class="red"><strong>
+ Note:<br>
+ </strong></span>
+ Not all drivers/NICs support 802.1Q VLAN tagging properly. On cards that do not explicitly support it, VLAN tagging will still work, but the reduced MTU may cause problems. See the m0n0wall homepage for information on supported cards. </p>
+ </td>
+ <td class="list">&nbsp;</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+</table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_vlan_edit.php b/usr/local/www/interfaces_vlan_edit.php
new file mode 100755
index 0000000..7932e2d
--- /dev/null
+++ b/usr/local/www/interfaces_vlan_edit.php
@@ -0,0 +1,146 @@
+#!/usr/local/bin/php
+<?php
+/*
+ interfaces_vlan_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['vlans']['vlan']))
+ $config['vlans']['vlan'] = array();
+
+$a_vlans = &$config['vlans']['vlan'];
+
+$portlist = get_interface_list();
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_vlans[$id]) {
+ $pconfig['if'] = $a_vlans[$id]['if'];
+ $pconfig['tag'] = $a_vlans[$id]['tag'];
+ $pconfig['descr'] = $a_vlans[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "if tag");
+ $reqdfieldsn = explode(",", "Parent interface,VLAN tag");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if ($_POST['tag'] && (!is_numericint($_POST['tag']) || ($_POST['tag'] < '1') || ($_POST['tag'] > '4094'))) {
+ $input_errors[] = "The VLAN tag must be an integer between 1 and 4094.";
+ }
+
+ foreach ($a_vlans as $vlan) {
+ if (isset($id) && ($a_vlans[$id]) && ($a_vlans[$id] === $vlan))
+ continue;
+
+ if (($vlan['if'] == $_POST['if']) && ($vlan['tag'] == $_POST['tag'])) {
+ $input_errors[] = "A VLAN with the tag {$vlan['tag']} is already defined on this interface.";
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $vlan = array();
+ $vlan['if'] = $_POST['if'];
+ $vlan['tag'] = $_POST['tag'];
+ $vlan['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_vlans[$id])
+ $a_vlans[$id] = $vlan;
+ else
+ $a_vlans[] = $vlan;
+
+ write_config();
+ touch($d_sysrebootreqd_path);
+ header("Location: interfaces_vlan.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html><head>
+<title><?=gentitle("Interfaces: Assign network ports: VLANs: 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">Interfaces: Assign network ports: VLANs: Edit</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="interfaces_vlan_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">Parent interface</td>
+ <td width="78%" class="vtable">
+ <select name="if" class="formfld">
+ <?php
+ foreach ($portlist as $ifn => $ifinfo): ?>
+ <option value="<?=$ifn;?>" <?php if ($ifn == $pconfig['if']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifn . " (" . $ifinfo['mac'] . ")");?>
+ </option>
+ <?php endforeach; ?>
+ </select></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">VLAN tag </td>
+ <td class="vtable">
+ <input name="tag" type="text" class="formfld" id="tag" size="6" value="<?=htmlspecialchars($pconfig['tag']);?>">
+ <br>
+ <span class="vexpl">802.1Q VLAN tag (between 1 and 4094) </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_vlans[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_wan.php b/usr/local/www/interfaces_wan.php
new file mode 100755
index 0000000..b4cc30b
--- /dev/null
+++ b/usr/local/www/interfaces_wan.php
@@ -0,0 +1,630 @@
+#!/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['pppoe_dialondemand'] = $config['pppoe']['ondemand'];
+$pconfig['pppoe_idletimeout'] = $config['pppoe']['timeout'];
+
+$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['pptp_dialondemand'] = $config['pptp']['ondemand'];
+$pconfig['pptp_idletimeout'] = $config['pptp']['timeout'];
+
+$pconfig['bigpond_username'] = $config['bigpond']['username'];
+$pconfig['bigpond_password'] = $config['bigpond']['password'];
+$pconfig['bigpond_authserver'] = $config['bigpond']['authserver'];
+$pconfig['bigpond_authdomain'] = $config['bigpond']['authdomain'];
+$pconfig['bigpond_minheartbeatinterval'] = $config['bigpond']['minheartbeatinterval'];
+
+$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 if ($wancfg['ipaddr'] == "bigpond") {
+ $pconfig['type'] = "BigPond";
+} 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") {
+ if ($_POST['pppoe_dialondemand']) {
+ $reqdfields = explode(" ", "username password pppoe_dialondemand pppoe_idletimeout");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password,Dial on demand,Idle timeout value");
+ } else {
+ $reqdfields = explode(" ", "username password");
+ $reqdfieldsn = explode(",", "PPPoE username,PPPoE password");
+ }
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+ } else if ($_POST['type'] == "PPTP") {
+ if ($_POST['pptp_dialondemand']) {
+ $reqdfields = explode(" ", "pptp_username pptp_password pptp_local pptp_subnet pptp_remote pptp_dialondemand pptp_idletimeout");
+ $reqdfieldsn = explode(",", "PPTP username,PPTP password,PPTP local IP address,PPTP subnet,PPTP remote IP address,Dial on demand,Idle timeout value");
+ } else {
+ $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);
+ } else if ($_POST['type'] == "BigPond") {
+ $reqdfields = explode(" ", "bigpond_username bigpond_password");
+ $reqdfieldsn = explode(",", "BigPond username,BigPond password");
+ 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['pppoe_idletimeout'] && !is_numericint($_POST['pppoe_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ 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['pptp_idletimeout'] && !is_numericint($_POST['pptp_idletimeout'])) {
+ $input_errors[] = "The idle timeout value must be an integer.";
+ }
+ if (($_POST['bigpond_authserver'] && !is_domain($_POST['bigpond_authserver']))) {
+ $input_errors[] = "The authentication server name contains invalid characters.";
+ }
+ if (($_POST['bigpond_authdomain'] && !is_domain($_POST['bigpond_authdomain']))) {
+ $input_errors[] = "The authentication domain name contains invalid characters.";
+ }
+ if ($_POST['bigpond_minheartbeatinterval'] && !is_numericint($_POST['bigpond_minheartbeatinterval'])) {
+ $input_errors[] = "The minimum heartbeat interval must be an integer.";
+ }
+ 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['pppoe']['ondemand']);
+ unset($config['pppoe']['timeout']);
+ unset($config['pptp']['username']);
+ unset($config['pptp']['password']);
+ unset($config['pptp']['local']);
+ unset($config['pptp']['subnet']);
+ unset($config['pptp']['remote']);
+ unset($config['pptp']['ondemand']);
+ unset($config['pptp']['timeout']);
+ unset($config['bigpond']['username']);
+ unset($config['bigpond']['password']);
+ unset($config['bigpond']['authserver']);
+ unset($config['bigpond']['authdomain']);
+ unset($config['bigpond']['minheartbeatinterval']);
+
+ 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'];
+ $config['pppoe']['ondemand'] = $_POST['pppoe_dialondemand'];
+ $config['pppoe']['timeout'] = $_POST['pppoe_idletimeout'];
+ } 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'];
+ $config['pptp']['ondemand'] = $_POST['pptp_dialondemand'];
+ $config['pptp']['timeout'] = $_POST['pptp_idletimeout'];
+ } else if ($_POST['type'] == "BigPond") {
+ $wancfg['ipaddr'] = "bigpond";
+ $config['bigpond']['username'] = $_POST['bigpond_username'];
+ $config['bigpond']['password'] = $_POST['bigpond_password'];
+ $config['bigpond']['authserver'] = $_POST['bigpond_authserver'];
+ $config['bigpond']['authdomain'] = $_POST['bigpond_authdomain'];
+ $config['bigpond']['minheartbeatinterval'] = $_POST['bigpond_minheartbeatinterval'];
+ }
+
+ $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><?=gentitle("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 enable_change(enable_change) {
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.disabled = 1;
+ }
+}
+
+function enable_change_pptp(enable_change_pptp) {
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ document.iform.pptp_local.disabled = 0;
+ document.iform.pptp_remote.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+}
+
+function type_change(enable_change,enable_change_pptp) {
+ switch (document.iform.type.selectedIndex) {
+ case 0:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.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.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.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.pppoe_dialondemand.disabled = 0;
+ if (document.iform.pppoe_dialondemand.checked || enable_change) {
+ document.iform.pppoe_idletimeout.disabled = 0;
+ } else {
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.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.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 0;
+ if (document.iform.pptp_dialondemand.checked || enable_change_pptp) {
+ document.iform.pptp_idletimeout.disabled = 0;
+ } else {
+ document.iform.pptp_idletimeout.disabled = 1;
+ }
+ document.iform.bigpond_username.disabled = 1;
+ document.iform.bigpond_password.disabled = 1;
+ document.iform.bigpond_authserver.disabled = 1;
+ document.iform.bigpond_authdomain.disabled = 1;
+ document.iform.bigpond_minheartbeatinterval.disabled = 1;
+ document.iform.dhcphostname.disabled = 1;
+ break;
+ case 4:
+ document.iform.username.disabled = 1;
+ document.iform.password.disabled = 1;
+ document.iform.provider.disabled = 1;
+ document.iform.pppoe_dialondemand.disabled = 1;
+ document.iform.pppoe_idletimeout.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.pptp_dialondemand.disabled = 1;
+ document.iform.pptp_idletimeout.disabled = 1;
+ document.iform.bigpond_username.disabled = 0;
+ document.iform.bigpond_password.disabled = 0;
+ document.iform.bigpond_authserver.disabled = 0;
+ document.iform.bigpond_authdomain.disabled = 0;
+ document.iform.bigpond_minheartbeatinterval.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($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 BigPond");
+ 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 valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pppoe_dialondemand" type="checkbox" id="pppoe_dialondemand" value="enable" <?php if ($pconfig['pppoe_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pppoe_idletimeout" type="text" class="formfld" id="pppoe_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pppoe_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</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>
+ <tr>
+ <td valign="top" class="vncell">Dial on demand</td>
+ <td class="vtable"><input name="pptp_dialondemand" type="checkbox" id="pptp_dialondemand" value="enable" <?php if ($pconfig['pptp_dialondemand'] == "enable") echo "checked"; ?> onClick="enable_change_pptp(false)" >
+ <strong>Enable Dial-On-Demand mode</strong><br>
+ This option causes the interface to operate in dial-on-demand mode, allowing you to have a <i>virtual full time</i> connection. The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="pptp_idletimeout" type="text" class="formfld" id="pptp_idletimeout" size="8" value="<?=htmlspecialchars($pconfig['pptp_idletimeout']);?>">
+ seconds<br>
+ If no qualifying outgoing packets are transmitted for the specified number of seconds, the connection is brought down. An idle timeout of zero disables this feature.</td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" height="16"></td>
+ </tr>
+ <tr>
+ <td colspan="2" valign="top" class="vnsepcell">BigPond Cable configuration</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Username</td>
+ <td class="vtable"><input name="bigpond_username" type="text" class="formfld" id="bigpond_username" size="20" value="<?=htmlspecialchars($pconfig['bigpond_username']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Password</td>
+ <td class="vtable"><input name="bigpond_password" type="text" class="formfld" id="bigpond_password" size="20" value="<?=htmlspecialchars($pconfig['bigpond_password']);?>">
+ </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication server</td>
+ <td class="vtable"><input name="bigpond_authserver" type="text" class="formfld" id="bigpond_authserver" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authserver']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the default (&quot;dce-server&quot;) is used. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Authentication domain</td>
+ <td class="vtable"><input name="bigpond_authdomain" type="text" class="formfld" id="bigpond_authdomain" size="20" value="<?=htmlspecialchars($pconfig['bigpond_authdomain']);?>">
+ <br>
+ <span class="vexpl">If this field is left empty, the domain name assigned via DHCP will be used.<br>
+ <br>
+ Note: the BigPond client implicitly sets the &quot;Allow DNS server list to be overridden by DHCP/PPP on WAN&quot; on the System: General setup page. </span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Min. heartbeat interval</td>
+ <td class="vtable">
+ <input name="bigpond_minheartbeatinterval" type="text" class="formfld" id="bigpond_minheartbeatinterval" size="8" value="<?=htmlspecialchars($pconfig['bigpond_minheartbeatinterval']);?>">
+ seconds<br>
+ Setting this to a sensible value (e.g. 60 seconds) can protect against DoS attacks. </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" onClick="enable_change_pptp(true)&&enable_change(true)">
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+type_change();
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/interfaces_wlan.inc b/usr/local/www/interfaces_wlan.inc
new file mode 100755
index 0000000..8861ce6
--- /dev/null
+++ b/usr/local/www/interfaces_wlan.inc
@@ -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/usr/local/www/license.php b/usr/local/www/license.php
new file mode 100755
index 0000000..2cb9fdf
--- /dev/null
+++ b/usr/local/www/license.php
@@ -0,0 +1,187 @@
+#!/usr/local/bin/php
+<?php require("guiconfig.inc");
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("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; dial-on-demand</font></em><br>
+ <br>
+ Thierry Lechat (<a href="mailto:dev@lechat.org">dev@lechat.org</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">SVG-based traffic grapher</font></em><br>
+ <br>
+ Steven Honson (<a href="mailto:steven@honson.org">steven@honson.org</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">per-user IP address assignments for PPTP VPN</font></em><br>
+ <br>
+ Kurt Inge Smådal (<a href="mailto:kurt@emsp.no">kurt@emsp.no</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">NAT on optional interfaces</font></em><br>
+ <br>
+ Dinesh Nair (<a href="mailto:dinesh@alphaque.com">dinesh@alphaque.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">captive portal: pass-through MAC/IP addresses, RADIUS authentication &amp; accounting;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666"></font></em>HTTP server concurrency limit</font></em><br>
+ <br>
+ Justin Ellison (<a href="mailto:justin@techadvise.com">justin@techadvise.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">traffic shaper TOS matching; magic shaper; DHCP deny unknown clients;<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;IPsec user FQDNs; DHCP relay</font></em><br>
+ <br>
+ Fred Wright (<a href="mailto:fw@well.com">fw@well.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">ipfilter window scaling fix; ipnat ICMP checksum adjustment fix; IPsec dead SA fixes</font></em><br>
+ <br>
+ Michael Hanselmann (<a href="mailto:m0n0@hansmi.ch">m0n0@hansmi.ch</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">IDE hard disk standby</font></em><br>
+ <br>
+ Audun Larsen (<a href="mailto:larsen@xqus.com">larsen@xqus.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">CPU/memory usage display</font></em><br>
+ <br>
+ Peter Curran (<a href="mailto:peter@closeconsultants.com">peter@closeconsultants.com</a>)<br>
+ &nbsp;&nbsp;&nbsp;&nbsp;<em><font color="#666666">OpenVPN support</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; 2003-2004, Archie L. Cobbs, Michael Bretterklieber, Alexander Motin<br>
+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)<br>
+ <br>
+ BPALogin (<a href="http://bpalogin.sourceforge.net/" target="_blank">http://bpalogin.sourceforge.net</a>) - lightweight portable BIDS2 login client<br>
+ Copyright &copy; 2001-3 Shane Hyde, and others.<br>
+ <br>
+ php-radius (<a href="http://www.mavetju.org/programming/php.php" target="_blank">http://www.mavetju.org/programming/php.php</a>)<br>
+ Copyright 2000, 2001, 2002 by Edwin Groothuis. All rights reserved.<br>
+ This product includes software developed by Edwin Groothuis.<br>
+ <br>
+ wol (<a href="http://ahh.sourceforge.net/wol" target="_blank">http://ahh.sourceforge.net/wol</a>)<br>
+ Copyright &copy; 2000,2001,2002,2003,2004 Thomas Krennwallner &lt;krennwallner@aon.at&gt;
+ <?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/logobig.jpg b/usr/local/www/logobig.jpg
new file mode 100755
index 0000000..d3143e7
--- /dev/null
+++ b/usr/local/www/logobig.jpg
Binary files differ
diff --git a/usr/local/www/reboot.php b/usr/local/www/reboot.php
new file mode 100755
index 0000000..0dbd6d1
--- /dev/null
+++ b/usr/local/www/reboot.php
@@ -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><?=gentitle("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($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/usr/local/www/services_captiveportal.php b/usr/local/www/services_captiveportal.php
new file mode 100755
index 0000000..99fb152
--- /dev/null
+++ b/usr/local/www/services_captiveportal.php
@@ -0,0 +1,396 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal.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['captiveportal'])) {
+ $config['captiveportal'] = array();
+ $config['captiveportal']['page'] = array();
+ $config['captiveportal']['timeout'] = 60;
+}
+
+if ($_GET['act'] == "viewhtml") {
+ echo base64_decode($config['captiveportal']['page']['htmltext']);
+ exit;
+} else if ($_GET['act'] == "viewerrhtml") {
+ echo base64_decode($config['captiveportal']['page']['errtext']);
+ exit;
+}
+
+$pconfig['cinterface'] = $config['captiveportal']['interface'];
+$pconfig['timeout'] = $config['captiveportal']['timeout'];
+$pconfig['idletimeout'] = $config['captiveportal']['idletimeout'];
+$pconfig['enable'] = isset($config['captiveportal']['enable']);
+$pconfig['radacct_enable'] = isset($config['captiveportal']['radacct_enable']);
+$pconfig['httpslogin_enable'] = isset($config['captiveportal']['httpslogin']);
+$pconfig['httpsname'] = $config['captiveportal']['httpsname'];
+$pconfig['cert'] = base64_decode($config['captiveportal']['certificate']);
+$pconfig['key'] = base64_decode($config['captiveportal']['private-key']);
+$pconfig['logoutwin_enable'] = isset($config['captiveportal']['logoutwin_enable']);
+$pconfig['nomacfilter'] = isset($config['captiveportal']['nomacfilter']);
+$pconfig['redirurl'] = $config['captiveportal']['redirurl'];
+$pconfig['radiusip'] = $config['captiveportal']['radiusip'];
+$pconfig['radiusport'] = $config['captiveportal']['radiusport'];
+$pconfig['radiusacctport'] = $config['captiveportal']['radiusacctport'];
+$pconfig['radiuskey'] = $config['captiveportal']['radiuskey'];
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "cinterface");
+ $reqdfieldsn = explode(",", "Interface");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ /* make sure no interfaces are bridged */
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ $coptif = &$config['interfaces']['opt' . $i];
+ if (isset($coptif['enable']) && $coptif['bridge']) {
+ $input_errors[] = "The captive portal cannot be used when one or more interfaces are bridged.";
+ break;
+ }
+ }
+
+ if ($_POST['httpslogin_enable']) {
+ if (!$_POST['cert'] || !$_POST['key']) {
+ $input_errors[] = "Certificate and key must be specified for HTTPS login.";
+ } else {
+ 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 (!$_POST['httpsname'] || !is_domain($_POST['httpsname'])) {
+ $input_errors[] = "The HTTPS server name must be specified for HTTPS login.";
+ }
+ }
+ }
+
+ if ($_POST['timeout'] && (!is_numeric($_POST['timeout']) || ($_POST['timeout'] < 1))) {
+ $input_errors[] = "The timeout must be at least 1 minute.";
+ }
+ if ($_POST['idletimeout'] && (!is_numeric($_POST['idletimeout']) || ($_POST['idletimeout'] < 1))) {
+ $input_errors[] = "The idle timeout must be at least 1 minute.";
+ }
+ if (($_POST['radiusip'] && !is_ipaddr($_POST['radiusip']))) {
+ $input_errors[] = "A valid IP address must be specified. [".$_POST['radiusip']."]";
+ }
+ if (($_POST['radiusport'] && !is_port($_POST['radiusport']))) {
+ $input_errors[] = "A valid port number must be specified. [".$_POST['radiusport']."]";
+ }
+ if (($_POST['radiusacctport'] && !is_port($_POST['radiusacctport']))) {
+ $input_errors[] = "A valid port number must be specified. [".$_POST['radiusport']."]";
+ }
+
+ if (!$input_errors) {
+ $config['captiveportal']['interface'] = $_POST['cinterface'];
+ $config['captiveportal']['timeout'] = $_POST['timeout'];
+ $config['captiveportal']['idletimeout'] = $_POST['idletimeout'];
+ $config['captiveportal']['enable'] = $_POST['enable'] ? true : false;
+ $config['captiveportal']['radacct_enable'] = $_POST['radacct_enable'] ? true : false;
+ $config['captiveportal']['httpslogin'] = $_POST['httpslogin_enable'] ? true : false;
+ $config['captiveportal']['httpsname'] = $_POST['httpsname'];
+ $config['captiveportal']['certificate'] = base64_encode($_POST['cert']);
+ $config['captiveportal']['private-key'] = base64_encode($_POST['key']);
+ $config['captiveportal']['logoutwin_enable'] = $_POST['logoutwin_enable'] ? true : false;
+ $config['captiveportal']['nomacfilter'] = $_POST['nomacfilter'] ? true : false;
+ $config['captiveportal']['redirurl'] = $_POST['redirurl'];
+ $config['captiveportal']['radiusip'] = $_POST['radiusip'];
+ $config['captiveportal']['radiusport'] = $_POST['radiusport'];
+ $config['captiveportal']['radiusacctport'] = $_POST['radiusacctport'];
+ $config['captiveportal']['radiuskey'] = $_POST['radiuskey'];
+
+ /* file upload? */
+ if (is_uploaded_file($_FILES['htmlfile']['tmp_name']))
+ $config['captiveportal']['page']['htmltext'] = base64_encode(file_get_contents($_FILES['htmlfile']['tmp_name']));
+ if (is_uploaded_file($_FILES['errfile']['tmp_name']))
+ $config['captiveportal']['page']['errtext'] = base64_encode(file_get_contents($_FILES['errfile']['tmp_name']));
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = captiveportal_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal");?></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 radacct_change() {
+ if (document.iform.radacct_enable.checked) {
+ document.iform.logoutwin_enable.checked = 1;
+ }
+}
+
+function enable_change(enable_change) {
+ if (document.iform.enable.checked || enable_change) {
+ document.iform.cinterface.disabled = 0;
+ document.iform.idletimeout.disabled = 0;
+ document.iform.timeout.disabled = 0;
+ document.iform.redirurl.disabled = 0;
+ document.iform.radiusip.disabled = 0;
+ document.iform.radiusport.disabled = 0;
+ document.iform.radiuskey.disabled = 0;
+ document.iform.radacct_enable.disabled = 0;
+ document.iform.httpslogin_enable.disabled = 0;
+ document.iform.httpsname.disabled = 0;
+ document.iform.cert.disabled = 0;
+ document.iform.key.disabled = 0;
+ document.iform.logoutwin_enable.disabled = 0;
+ document.iform.nomacfilter.disabled = 0;
+ document.iform.htmlfile.disabled = 0;
+ document.iform.errfile.disabled = 0;
+ } else {
+ document.iform.cinterface.disabled = 1;
+ document.iform.idletimeout.disabled = 1;
+ document.iform.timeout.disabled = 1;
+ document.iform.redirurl.disabled = 1;
+ document.iform.radiusip.disabled = 1;
+ document.iform.radiusport.disabled = 1;
+ document.iform.radiuskey.disabled = 1;
+ document.iform.radacct_enable.disabled = 1;
+ document.iform.httpslogin_enable.disabled = 1;
+ document.iform.httpsname.disabled = 1;
+ document.iform.cert.disabled = 1;
+ document.iform.key.disabled = 1;
+ document.iform.logoutwin_enable.disabled = 1;
+ document.iform.nomacfilter.disabled = 1;
+ document.iform.htmlfile.disabled = 1;
+ document.iform.errfile.disabled = 1;
+ }
+ if (enable_change && document.iform.radacct_enable.checked) {
+ document.iform.logoutwin_enable.checked = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: Captive portal</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<form action="services_captiveportal.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Captive portal</li>
+ <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
+ <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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 captive portal </strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface</td>
+ <td width="78%" class="vtable">
+ <select name="cinterface" class="formfld" id="cinterface">
+ <?php $interfaces = array('lan' => 'LAN');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if (isset($config['interfaces']['opt' . $i]['enable']))
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $pconfig['cinterface']) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which interface to run the captive portal on.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Idle timeout</td>
+ <td class="vtable">
+ <input name="idletimeout" type="text" class="formfld" id="idletimeout" size="6" value="<?=htmlspecialchars($pconfig['idletimeout']);?>">
+minutes<br>
+Clients will be disconnected after this amount of inactivity. They may log in again immediately, though. Leave this field blank for no idle timeout.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Hard timeout</td>
+ <td width="78%" class="vtable">
+ <input name="timeout" type="text" class="formfld" id="timeout" size="6" value="<?=htmlspecialchars($pconfig['timeout']);?>">
+ minutes<br>
+ Clients will be disconnected after this amount of time, regardless of activity. They may log in again immediately, though. Leave this field blank for no hard timeout (not recommended unless an idle timeout is set).</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Logout popup window</td>
+ <td width="78%" class="vtable">
+ <input name="logoutwin_enable" type="checkbox" class="formfld" id="logoutwin_enable" value="yes" <?php if($pconfig['logoutwin_enable']) echo "checked"; ?>>
+ <strong>Enable logout popup window</strong><br>
+ If enabled, a popup window will appear when clients are allowed through the captive portal. This allows clients to explicitly disconnect themselves before the idle or hard timeout occurs. When RADIUS accounting is enabled, this option is implied.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">Redirection URL</td>
+ <td class="vtable">
+ <input name="redirurl" type="text" class="formfld" id="redirurl" size="60" value="<?=htmlspecialchars($pconfig['redirurl']);?>">
+ <br>
+If you provide a URL here, clients will be redirected to that URL instead of the one they initially tried
+to access after they've authenticated.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">MAC filtering </td>
+ <td class="vtable">
+ <input name="nomacfilter" type="checkbox" class="formfld" id="nomacfilter" value="yes" <?php if ($pconfig['nomacfilter']) echo "checked"; ?>>
+ <strong>Disable MAC filtering</strong><br>
+ If this option is set, no attempts will be made to ensure that the MAC address of clients stays the same while they're logged in. This is required when the MAC address of cannot be determined (usually because there are routers between m0n0wall and the clients).</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">RADIUS server</td>
+ <td width="78%" class="vtable">
+ <table cellpadding="0" cellspacing="0">
+ <tr>
+ <td>IP address:</td>
+ <td><input name="radiusip" type="text" class="formfld" id="radiusip" size="20" value="<?=htmlspecialchars($pconfig['radiusip']);?>"></td>
+ </tr><tr>
+ <td>Port:</td>
+ <td><input name="radiusport" type="text" class="formfld" id="radiusport" size="5" value="<?=htmlspecialchars($pconfig['radiusport']);?>"></td>
+ </tr><tr>
+ <td>Shared secret:&nbsp;&nbsp;</td>
+ <td><input name="radiuskey" type="text" class="formfld" id="radiuskey" size="16" value="<?=htmlspecialchars($pconfig['radiuskey']);?>"> </td>
+ </tr>
+ <tr>
+ <td>Accounting:&nbsp;&nbsp;</td>
+ <td><input name="radacct_enable" type="checkbox" id="radacct_enable" value="yes" <?php if($pconfig['radacct_enable']) echo "checked"; ?> onClick="radacct_change()"></td>
+ </tr>
+ <tr>
+ <td>Accounting port:&nbsp;&nbsp;</td>
+ <td><input name="radiusacctport" type="text" class="formfld" id="radiusacctport" size="5" value="<?=htmlspecialchars($pconfig['radiusacctport']);?>"></td>
+ </tr></table>
+ <br>
+ Enter the IP address and port of the RADIUS server which users of the captive portal have to authenticate against. Leave blank to disable RADIUS authentication. Leave port number blank to use the default port (1812). Leave the RADIUS shared secret blank to not use a RADIUS shared secret. RADIUS accounting packets will also be sent to the RADIUS server if accounting is enabled (default port is 1813).
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">HTTPS login</td>
+ <td class="vtable">
+ <input name="httpslogin_enable" type="checkbox" class="formfld" id="httpslogin_enable" value="yes" <?php if($pconfig['httpslogin_enable']) echo "checked"; ?>>
+ <strong>Enable HTTPS login</strong><br>
+ If enabled, the username and password will be transmitted over an HTTPS connection to protect against eavesdroppers. This option only applies when RADIUS authentication is used. A server name, certificate and matching private key must also be specified below.</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">HTTPS server name </td>
+ <td class="vtable">
+ <input name="httpsname" type="text" class="formfld" id="httpsname" size="30" value="<?=htmlspecialchars($pconfig['httpsname']);?>"><br>
+ This name will be used in the form action for the HTTPS POST and should match the Common Name (CN) in your certificate (otherwise, the client browser will most likely display a security warning). Make sure captive portal clients can resolve this name in DNS. </td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">HTTPS certificate</td>
+ <td 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 valign="top" class="vncell">HTTPS private key</td>
+ <td 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" class="vncellreq">Portal page contents</td>
+ <td width="78%" class="vtable">
+ <input type="file" name="htmlfile" class="formfld" id="htmlfile"><br>
+ <?php if ($config['captiveportal']['page']['htmltext']): ?>
+ <a href="?act=viewhtml" target="_blank">View current page</a>
+ <br>
+ <br>
+ <?php endif; ?>
+ Upload an HTML file for the portal page here (leave blank to keep the current one). Make sure to include a form (POST to &quot;$PORTAL_ACTION$&quot;)
+with a submit button (name=&quot;accept&quot;). Include the &quot;auth_user&quot; and &quot;auth_pass&quot; input elements if RADIUS authentication is enabled. If RADIUS is enabled and no &quot;auth_user&quot; is present, authentication will always fail. If RADIUS is not enabled, you can omit both these input elements.
+When using HTTPS login, a hidden field with name=&quot;redirurl&quot; and value=&quot;$PORTAL_REDIRURL$&quot; has to be included as well. Example code for the form:<br>
+ <br>
+ <tt>&lt;form method=&quot;post&quot; action=&quot;$PORTAL_ACTION$&quot;&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_user&quot; type=&quot;text&quot;&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;input name=&quot;auth_pass&quot; type=&quot;password&quot;&gt;<br>
+ &nbsp;&nbsp;&nbsp;&lt;input name=&quot;redirurl&quot; type=&quot;hidden&quot; value=&quot;$PORTAL_REDIRURL$&quot;&gt;<br>
+&nbsp;&nbsp;&nbsp;&lt;input name=&quot;accept&quot; type=&quot;submit&quot; value=&quot;Continue&quot;&gt;<br>
+ &lt;/form&gt;</tt></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Authentication<br>
+ error page<br>
+ contents</td>
+ <td class="vtable">
+ <input name="errfile" type="file" class="formfld" id="errfile"><br>
+ <?php if ($config['captiveportal']['page']['errtext']): ?>
+ <a href="?act=viewerrhtml" target="_blank">View current page</a>
+ <br>
+ <br>
+ <?php endif; ?>
+The contents of the HTML file that you upload here are displayed when a RADIUS authentication error occurs.</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>Changing any settings on this page will disconnect all clients! Don't forget to enable the DHCP server on your captive portal interface! Make sure that the default/maximum DHCP lease time is higher than the timeout entered on this page. Also, the DNS forwarder needs to be enabled for DNS lookups by unauthenticated clients to work. </span></td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal_ip.php b/usr/local/www/services_captiveportal_ip.php
new file mode 100755
index 0000000..b3d406a
--- /dev/null
+++ b/usr/local/www/services_captiveportal_ip.php
@@ -0,0 +1,152 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_ip.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
+ 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['captiveportal']['allowedip']))
+ $config['captiveportal']['allowedip'] = array();
+
+allowedips_sort();
+$a_allowedips = &$config['captiveportal']['allowedip'] ;
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ $retval = captiveportal_allowedip_configure();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_allowedipsdirty_path)) {
+ config_lock();
+ unlink($d_allowedipsdirty_path);
+ config_unlock();
+ }
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_allowedips[$_GET['id']]) {
+ unset($a_allowedips[$_GET['id']]);
+ write_config();
+ touch($d_allowedipsdirty_path);
+ header("Location: services_captiveportal_ip.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal");?></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: Captive portal: Allowed IP addresses</p>
+<form action="services_captiveportal_ip.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_allowedipsdirty_path)): ?><p>
+<?php print_info_box_np("The captive portal IP address 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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="services_captiveportal.php">Captive portal</a></li>
+ <li class="tabinact"><a href="services_captiveportal_mac.php">Pass-through MAC</a></li>
+ <li class="tabact">Allowed IP addresses</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr">IP address</td>
+ <td width="60%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_allowedips as $ip): ?>
+ <tr>
+ <td class="listlr">
+ <?php if($ip['dir'] == "to")
+ echo "any <img src=\"in.gif\" width=\"11\" height=\"11\" align=\"absmiddle\">";
+ ?>
+ <?=strtolower($ip['ip']);?>
+ <?php if($ip['dir'] == "from")
+ echo "<img src=\"in.gif\" width=\"11\" height=\"11\" align=\"absmiddle\"> any";
+ ?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($ip['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_captiveportal_ip_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_captiveportal_ip.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this address?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="2">&nbsp;</td>
+ <td class="list"> <a href="services_captiveportal_ip_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list"><p class="vexpl"><span class="red"><strong>
+ Note:<br>
+ </strong></span>
+ Adding allowed IP addresses will allow IP access to/from these addresses through the captive portal without being taken to the portal page. This can be used for a web server serving images for the portal page or a DNS server on another network, for example. By specifying <em>from</em> addresses, it may be used to always allow pass-through access from a client behind the captive portal.</p>
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><span class="vexpl">any <img src="in.gif" width="11" height="11" align="absmiddle"> x.x.x.x </span></td>
+ <td><span class="vexpl">All connections <strong>to</strong> the IP address are allowed</span></td>
+ </tr>
+ <tr>
+ <td colspan="5" height="4"></td>
+ </tr>
+ <tr>
+ <td>x.x.x.x <span class="vexpl"><img src="in.gif" width="11" height="11" align="absmiddle"></span> any&nbsp;&nbsp;&nbsp; </td>
+ <td><span class="vexpl">All connections <strong>from</strong> the IP address are allowed </span></td>
+ </tr>
+ </table></td>
+ <td class="list">&nbsp;</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal_ip_edit.php b/usr/local/www/services_captiveportal_ip_edit.php
new file mode 100755
index 0000000..4b1cecf
--- /dev/null
+++ b/usr/local/www/services_captiveportal_ip_edit.php
@@ -0,0 +1,152 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_ip_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
+ 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['captiveportal']['allowedip']))
+ $config['captiveportal']['allowedip'] = array();
+
+allowedips_sort();
+$a_allowedips = &$config['captiveportal']['allowedip'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_allowedips[$id]) {
+ $pconfig['ip'] = $a_allowedips[$id]['ip'];
+ $pconfig['descr'] = $a_allowedips[$id]['descr'];
+ $pconfig['dir'] = $a_allowedips[$id]['dir'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "ip dir");
+ $reqdfieldsn = explode(",", "Allowed IP address,Direction");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
+ $input_errors[] = "A valid IP address must be specified. [".$_POST['ip']."]";
+ }
+
+ foreach ($a_allowedips as $ipent) {
+ if (isset($id) && ($a_allowedips[$id]) && ($a_allowedips[$id] === $ipent))
+ continue;
+
+ if (($ipent['dir'] == $_POST['dir']) && ($ipent['ip'] == $_POST['ip'])){
+ $input_errors[] = "[" . $_POST['ip'] . "] already allowed." ;
+ break ;
+ }
+ }
+
+ if (!$input_errors) {
+ $ip = array();
+ $ip['ip'] = $_POST['ip'];
+ $ip['descr'] = $_POST['descr'];
+ $ip['dir'] = $_POST['dir'];
+
+ if (isset($id) && $a_allowedips[$id])
+ $a_allowedips[$id] = $ip;
+ else
+ $a_allowedips[] = $ip;
+
+ write_config();
+
+ touch($d_allowedipsdirty_path) ;
+
+ header("Location: services_captiveportal_ip.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal: Edit allowed IP address");?></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: Captive portal: Edit allowed IP address</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_captiveportal_ip_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">Direction</td>
+ <td width="78%" class="vtable">
+ <select name="dir" class="formfld">
+ <?php
+ $dirs = explode(" ", "From To") ;
+ foreach ($dirs as $dir): ?>
+ <option value="<?=strtolower($dir);?>" <?php if (strtolower($dir) == strtolower($pconfig['dir'])) echo "selected";?> >
+ <?=htmlspecialchars($dir);?>
+ </option>
+ <?php endforeach; ?>
+ </select>
+ <br>
+ <span class="vexpl">Use <em>From</em> to always allow an IP address through the captive portal (without authentication).
+ Use <em>To</em> to allow access from all clients (even non-authenticated ones) behind the portal to this IP address.</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="17" value="<?=htmlspecialchars($pconfig['ip']);?>">
+ <br>
+ <span class="vexpl">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_allowedips[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal_mac.php b/usr/local/www/services_captiveportal_mac.php
new file mode 100755
index 0000000..d38c58c
--- /dev/null
+++ b/usr/local/www/services_captiveportal_mac.php
@@ -0,0 +1,133 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_mac.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
+ 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['captiveportal']['passthrumac']))
+ $config['captiveportal']['passthrumac'] = array();
+
+passthrumacs_sort();
+$a_passthrumacs = &$config['captiveportal']['passthrumac'] ;
+
+if ($_POST) {
+
+ $pconfig = $_POST;
+
+ if ($_POST['apply']) {
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ $retval = captiveportal_passthrumac_configure();
+ }
+ $savemsg = get_std_save_message($retval);
+ if ($retval == 0) {
+ if (file_exists($d_passthrumacsdirty_path)) {
+ config_lock();
+ unlink($d_passthrumacsdirty_path);
+ config_unlock();
+ }
+ }
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_passthrumacs[$_GET['id']]) {
+ unset($a_passthrumacs[$_GET['id']]);
+ write_config();
+ touch($d_passthrumacsdirty_path);
+ header("Location: services_captiveportal_mac.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal");?></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: Captive portal: Pass-through MAC addresses</p>
+<form action="services_captiveportal_mac.php" method="post">
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<?php if (file_exists($d_passthrumacsdirty_path)): ?><p>
+<?php print_info_box_np("The captive portal MAC address 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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="services_captiveportal.php">Captive portal</a></li>
+ <li class="tabact">Pass-through MAC</li>
+ <li class="tabinact"><a href="services_captiveportal_ip.php">Allowed IP addresses</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="30%" class="listhdrr">MAC address</td>
+ <td width="60%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_passthrumacs as $mac): ?>
+ <tr>
+ <td class="listlr">
+ <?=strtolower($mac['mac']);?>
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($mac['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_captiveportal_mac_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_captiveportal_mac.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="2">&nbsp;</td>
+ <td class="list"> <a href="services_captiveportal_mac_edit.php"><img src="plus.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <tr>
+ <td colspan="2" class="list"><span class="vexpl"><span class="red"><strong>
+ Note:<br>
+ </strong></span>
+ Adding MAC addresses as pass-through MACs allows them access through the captive portal automatically without being taken to the portal page. The pass-through MACs can change their IP addresses on the fly and upon the next access, the pass-through tables are changed accordingly. Pass-through MACs will however still be disconnected after the captive portal timeout period.</span></td>
+ <td class="list">&nbsp;</td>
+ </tr>
+ </table>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_captiveportal_mac_edit.php b/usr/local/www/services_captiveportal_mac_edit.php
new file mode 100755
index 0000000..f763bac
--- /dev/null
+++ b/usr/local/www/services_captiveportal_mac_edit.php
@@ -0,0 +1,134 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_captiveportal_mac_edit.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2004 Dinesh Nair <dinesh@alphaque.com>
+ 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['captiveportal']['passthrumac']))
+ $config['captiveportal']['passthrumac'] = array();
+
+passthrumacs_sort();
+$a_passthrumacs = &$config['captiveportal']['passthrumac'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_passthrumacs[$id]) {
+ $pconfig['mac'] = $a_passthrumacs[$id]['mac'];
+ $pconfig['descr'] = $a_passthrumacs[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "mac");
+ $reqdfieldsn = explode(",", "MAC address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['mac'] && !is_macaddr($_POST['mac']))) {
+ $input_errors[] = "A valid MAC address must be specified. [".$_POST['mac']."]";
+ }
+
+ foreach ($a_passthrumacs as $macent) {
+ if (isset($id) && ($a_passthrumacs[$id]) && ($a_passthrumacs[$id] === $macent))
+ continue;
+
+ if ($macent['mac'] == $_POST['mac']){
+ $input_errors[] = "[" . $_POST['mac'] . "] already allowed." ;
+ break;
+ }
+ }
+
+ if (!$input_errors) {
+ $mac = array();
+ $mac['mac'] = $_POST['mac'];
+ $mac['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_passthrumacs[$id])
+ $a_passthrumacs[$id] = $mac;
+ else
+ $a_passthrumacs[] = $mac;
+
+ write_config();
+
+ touch($d_passthrumacsdirty_path) ;
+
+ header("Location: services_captiveportal_mac.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Captive portal: Edit pass-through MAC address");?></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: Captive portal: Edit pass-through MAC address</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_captiveportal_mac_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">MAC address</td>
+ <td width="78%" class="vtable">
+ <input name="mac" type="text" class="formfld" id="mac" size="17" value="<?=htmlspecialchars($pconfig['mac']);?>">
+ <br>
+ <span class="vexpl">MAC address (6 hex octets separated by colons)</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_passthrumacs[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dhcp.php b/usr/local/www/services_dhcp.php
new file mode 100755
index 0000000..5b35b6a
--- /dev/null
+++ b/usr/local/www/services_dhcp.php
@@ -0,0 +1,337 @@
+#!/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']);
+$pconfig['denyunknown'] = isset($config['dhcpd'][$if]['denyunknown']);
+
+$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).";
+
+ /* make sure that the DHCP Relay isn't enabled on this interface */
+ if (isset($config['dhcrelay'][$if]['enable']))
+ $input_errors[] = "You must disable the DHCP relay on the {$iflist[$if]} interface before enabling the DHCP server.";
+ }
+ }
+
+ 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;
+ $config['dhcpd'][$if]['denyunknown'] = $_POST['denyunknown'] ? 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><?=gentitle("Services: DHCP server");?></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 server</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($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><td>
+ <ul id="tabnav">
+<?php foreach ($iflist as $ifent => $ifname):
+ if ($ifent == $if): ?>
+ <li class="tabact"><?=htmlspecialchars($ifname);?></li>
+<?php else: ?>
+ <li class="tabinact"><a href="services_dhcp.php?if=<?=$ifent;?>"><?=htmlspecialchars($ifname);?></a></li>
+<?php endif; ?>
+<?php endforeach; ?>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="denyunknown" type="checkbox" value="yes" <?php if ($pconfig['denyunknown']) echo "checked"; ?>>
+ <strong>Deny unknown clients</strong><br>
+ If this is checked, only the clients defined below will get DHCP leases from this server. </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>
+ </span></p></td>
+ </tr>
+ </table>
+ &nbsp;<br>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="35%" class="listhdrr">MAC address </td>
+ <td width="20%" class="listhdrr">IP address</td>
+ <td width="35%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_maps as $mapent): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($mapent['mac']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($mapent['ipaddr']);?>&nbsp;
+ </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/usr/local/www/services_dhcp_edit.php b/usr/local/www/services_dhcp_edit.php
new file mode 100755
index 0000000..80f64a9
--- /dev/null
+++ b/usr/local/www/services_dhcp_edit.php
@@ -0,0 +1,176 @@
+#!/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");
+ $reqdfieldsn = explode(",", "MAC 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']) || ($_POST['ipaddr'] && (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 */
+ if ($_POST['ipaddr']) {
+ $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><?=gentitle("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); ?>
+ <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">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">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ipaddr" type="text" class="formfld" id="ipaddr" size="20" value="<?=htmlspecialchars($pconfig['ipaddr']);?>">
+ <br>
+ If no IP address is given, one will be dynamically allocated from the pool.</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/usr/local/www/services_dhcp_relay.php b/usr/local/www/services_dhcp_relay.php
new file mode 100755
index 0000000..674077c
--- /dev/null
+++ b/usr/local/www/services_dhcp_relay.php
@@ -0,0 +1,229 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_dhcp.php
+ part of m0n0wall (http://m0n0.ch/wall)
+
+ Copyright (C) 2003-2004 Justin Ellison <justin@techadvise.com>.
+ 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 get_wan_dhcp_server() {
+ global $config, $g;
+ $dhclientfn = $g['vardb_path'] . "/dhclient.leases";
+ $leases = file($dhclientfn);
+ /* Start at the end, work backwards finding the latest lease for the WAN */
+ for ($i = (count($leases)-1); $i >= 0; $i--) {
+ if ($leases[$i] == "}") {
+ unset($iface);
+ unset($dhcpserver);
+ } elseif (strstr($leases[$i],"interface")) {
+ preg_match("/\s+interface \"(\w+)\";/",$leases[$i],$iface);
+ } elseif (strstr($leases[$i],"dhcp-server-identifier")) {
+ preg_match("/\s+dhcp-server-identifier (\d+\.\d+\.\d+\.\d+);/",$leases[$i],$dhcpserver);
+ }
+ if ($iface == $config['interfaces']['wan'] && isset($dhcpserver)) {
+ break;
+ }
+ }
+ return $dhcpserver[1];
+}
+
+
+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['enable'] = isset($config['dhcrelay'][$if]['enable']);
+$pconfig['server'] = $config['dhcrelay']['server'];
+$pconfig['proxydhcp'] = isset($config['dhcrelay']['proxydhcp']);
+$pconfig['agentoption'] = isset($config['dhcrelay']['agentoption']);
+
+$ifcfg = $config['interfaces'][$if];
+
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ if ($_POST['enable']) {
+ if (isset($_POST['proxydhcp']))
+ $_POST['server'] = get_wan_dhcp_server();
+ $reqdfields = explode(" ", "server");
+ $reqdfieldsn = explode(",", "Destination Server");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['server'] && !is_ipaddr($_POST['server'])))
+ $input_errors[] = "A valid Destination Server IP address must be specified.";
+
+ if (!$input_errors) {
+ /* make sure that the DHCP server isn't enabled on this interface */
+ if (isset($config['dhcpd'][$if]['enable']))
+ $input_errors[] = "You must disable the DHCP server on the {$iflist[$if]} interface before enabling the DHCP Relay.";
+ /* make sure that the DHCP server isn't running on any of the implied interfaces */
+ foreach ($config['interfaces'] as $ifname => $ifcfg) {
+ $subnet = $ifcfg['ipaddr'] . "/" . $ifcfg['subnet'];
+ if (ip_in_subnet($_POST['server'],$subnet))
+ $destif = $ifname;
+ }
+ if (!isset($destif))
+ $destif = "wan";
+ if (isset($config['dhcpd'][$destif]['enable']))
+ $input_errors[] = "You must disable the DHCP server on the {$destif} interface before enabling the DHCP Relay.";
+
+ /* if proxydhcp is selected, make sure DHCP is enabled on WAN */
+ if (isset($config['dhcrelay']['proxydhcp']) && $config['interfaces']['wan']['ipaddr'] != "dhcp")
+ $input_errors[] = "You must have DHCP active on the WAN interface before enabling the DHCP proxy option.";
+ }
+ }
+
+ if (!$input_errors) {
+ $config['dhcrelay']['agentoption'] = $_POST['agentoption'] ? true : false;
+ $config['dhcrelay']['proxydhcp'] = $_POST['proxydhcp'] ? true : false;
+ $config['dhcrelay']['server'] = $_POST['server'];
+ $config['dhcrelay'][$if]['enable'] = $_POST['enable'] ? true : false;
+
+ write_config();
+
+ $retval = 0;
+ if (!file_exists($d_sysrebootreqd_path)) {
+ config_lock();
+ $retval = services_dhcrelay_configure();
+ config_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: DHCP relay");?></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.server.disabled = 0;
+ document.iform.agentoption.disabled = 0;
+ document.iform.proxydhcp.disabled = 0;
+ } else {
+ document.iform.server.disabled = 1;
+ document.iform.agentoption.disabled = 1;
+ document.iform.proxydhcp.disabled = 1;
+ }
+ if (document.iform.proxydhcp.checked) {
+ document.iform.server.disabled = 1;
+ }
+}
+//-->
+</script>
+</head>
+
+<body link="#0000CC" vlink="#0000CC" alink="#0000CC">
+<?php include("fbegin.inc"); ?>
+<p class="pgtitle">Services: DHCP relay</p>
+<form action="services_dhcp_relay.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+<?php foreach ($iflist as $ifent => $ifname):
+ if ($ifent == $if): ?>
+ <li class="tabact"><?=htmlspecialchars($ifname);?></li>
+<?php else: ?>
+ <li class="tabinact"><a href="services_dhcp_relay.php?if=<?=$ifent;?>"><?=htmlspecialchars($ifname);?></a></li>
+<?php endif; ?>
+<?php endforeach; ?>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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 relay on
+ <?=htmlspecialchars($iflist[$if]);?>
+ interface</strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vtable">&nbsp;</td>
+ <td width="78%" class="vtable">
+<input name="agentoption" type="checkbox" value="yes" <?php if ($pconfig['agentoption']) echo "checked"; ?>>
+ <strong>Append circuit ID and agent ID to requests</strong><br>
+ If this is checked, the DHCP relay will append the circuit ID (m0n0wall interface number) and the agent ID to the DHCP request.</td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Destination server</td>
+ <td width="78%" class="vtable">
+ <input name="proxydhcp" type="checkbox" value="yes" <?php if ($pconfig['proxydhcp']) echo "checked"; ?> onClick="enable_change(false)"> Proxy requests to DHCP server on WAN subnet
+ <br><br><input name="server" type="text" class="formfld" id="server" size="20" value="<?=htmlspecialchars($pconfig['server']);?>">
+ <br>
+ This is the IP address of the server to which the DHCP packet is relayed. Select "Proxy requests to DHCP server on WAN subnet" to relay DHCP packets to the server that was used on the WAN interface.
+ </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>
+ </table>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/services_dnsmasq.php b/usr/local/www/services_dnsmasq.php
new file mode 100755
index 0000000..c69bb85
--- /dev/null
+++ b/usr/local/www/services_dnsmasq.php
@@ -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><?=gentitle("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($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="listhdr">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/usr/local/www/services_dnsmasq_edit.php b/usr/local/www/services_dnsmasq_edit.php
new file mode 100755
index 0000000..810a415
--- /dev/null
+++ b/usr/local/www/services_dnsmasq_edit.php
@@ -0,0 +1,160 @@
+#!/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><?=gentitle("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); ?>
+ <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/usr/local/www/services_dyndns.php b/usr/local/www/services_dyndns.php
new file mode 100755
index 0000000..e4864e6
--- /dev/null
+++ b/usr/local/www/services_dyndns.php
@@ -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><?=gentitle("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($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/usr/local/www/services_proxyarp.php b/usr/local/www/services_proxyarp.php
new file mode 100755
index 0000000..ecb7315
--- /dev/null
+++ b/usr/local/www/services_proxyarp.php
@@ -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><?=gentitle("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($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="listhdr">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/usr/local/www/services_proxyarp_edit.php b/usr/local/www/services_proxyarp_edit.php
new file mode 100755
index 0000000..2c5bd6c
--- /dev/null
+++ b/usr/local/www/services_proxyarp_edit.php
@@ -0,0 +1,231 @@
+#!/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><?=gentitle("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); ?>
+ <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/usr/local/www/services_snmp.php b/usr/local/www/services_snmp.php
new file mode 100755
index 0000000..e7c4464
--- /dev/null
+++ b/usr/local/www/services_snmp.php
@@ -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><?=gentitle("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($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/usr/local/www/services_wol.php b/usr/local/www/services_wol.php
new file mode 100755
index 0000000..1ee5946
--- /dev/null
+++ b/usr/local/www/services_wol.php
@@ -0,0 +1,162 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_wol.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['wol']['wolentry'])) {
+ $config['wol']['wolentry'] = array();
+}
+wol_sort();
+$a_wol = &$config['wol']['wolentry'];
+
+if ($_POST || $_GET['mac']) {
+ unset($input_errors);
+
+ if ($_GET['mac']) {
+ $mac = $_GET['mac'];
+ $if = $_GET['if'];
+ } else {
+ $mac = $_POST['mac_input'];
+ $if = $_POST['interface'];
+ }
+
+ /* input validation */
+ if (!$mac || !is_macaddr($mac))
+ $input_errors[] = "A valid MAC address must be specified.";
+ if (!$if)
+ $input_errors[] = "A valid interface must be specified.";
+
+ if (!$input_errors) {
+ /* determine broadcast address */
+ $bcip = gen_subnet_max($config['interfaces'][$if]['ipaddr'],
+ $config['interfaces'][$if]['subnet']);
+
+ mwexec("/usr/local/bin/wol -i {$bcip} {$mac}");
+ $savemsg = "Sent magic packet to {$mac}.";
+ }
+}
+
+if ($_GET['act'] == "del") {
+ if ($a_wol[$_GET['id']]) {
+ unset($a_wol[$_GET['id']]);
+ write_config();
+ header("Location: services_wol.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Wake on LAN");?></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: Wake on LAN</font></p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+ <form action="services_wol.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');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if (isset($config['interfaces']['opt' . $i]['enable']) &&
+ !$config['interfaces']['opt' . $i]['bridge'])
+ $interfaces['opt' . $i] = $config['interfaces']['opt' . $i]['descr'];
+ }
+ foreach ($interfaces as $iface => $ifacename): ?>
+ <option value="<?=$iface;?>" <?php if ($iface == $if) echo "selected"; ?>>
+ <?=htmlspecialchars($ifacename);?>
+ </option>
+ <?php endforeach; ?>
+ </select> <br>
+ <span class="vexpl">Choose which interface the host to be woken up is connected to.</span></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">MAC address</td>
+ <td width="78%" class="vtable">
+ <input name="mac_input" type="text" class="formfld" id="mac_input" size="20" value="<?=htmlspecialchars($mac);?>">
+ <br>
+ Enter a MAC address <span class="vexpl"> in the following format: xx:xx:xx:xx:xx:xx</span></td></tr>
+ <tr>
+ <td width="22%" valign="top">&nbsp;</td>
+ <td width="78%">
+ <input name="Submit" type="submit" class="formbtn" value="Send">
+ </td>
+ </tr>
+ </table>
+ <span class="vexpl"><span class="red"><strong>Note:<br>
+ </strong></span>This service can be used to wake up (power on) computers by sending special &quot;Magic Packets&quot;. The NIC in the computer that is to be woken up must support Wake on LAN and has to be configured properly (WOL cable, BIOS settings). </span><br>
+ <br>
+ You may store MAC addresses below for your convenience.
+Click the MAC address to wake up a computer. <br>
+&nbsp;
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="15%" class="listhdrr">Interface</td>
+ <td width="25%" class="listhdrr">MAC address</td>
+ <td width="50%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_wol as $wolent): ?>
+ <tr>
+ <td class="listlr">
+ <?php if ($wolent['interface'] == "lan")
+ echo "LAN";
+ else
+ echo $config['interfaces'][$wolent['interface']]['descr'];
+ ?>&nbsp;
+ </td>
+ <td class="listr">
+ <a href="?mac=<?=$wolent['mac'];?>&if=<?=$wolent['interface'];?>"><?=strtolower($wolent['mac']);?></a>&nbsp;
+ </td>
+ <td class="listbg">
+ <?=htmlspecialchars($wolent['descr']);?>&nbsp;
+ </td>
+ <td valign="middle" nowrap class="list"> <a href="services_wol_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="services_wol.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="3"></td>
+ <td class="list"> <a href="services_wol_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/usr/local/www/services_wol_edit.php b/usr/local/www/services_wol_edit.php
new file mode 100755
index 0000000..1d483f7
--- /dev/null
+++ b/usr/local/www/services_wol_edit.php
@@ -0,0 +1,143 @@
+#!/usr/local/bin/php
+<?php
+/*
+ services_wol_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['wol']['wolentry'])) {
+ $config['wol']['wolentry'] = array();
+}
+wol_sort();
+$a_wol = &$config['wol']['wolentry'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $a_wol[$id]) {
+ $pconfig['interface'] = $a_wol[$id]['interface'];
+ $pconfig['mac'] = $a_wol[$id]['mac'];
+ $pconfig['descr'] = $a_wol[$id]['descr'];
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+ $pconfig = $_POST;
+
+ /* input validation */
+ $reqdfields = explode(" ", "interface mac");
+ $reqdfieldsn = explode(",", "Interface,MAC address");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ if (($_POST['mac'] && !is_macaddr($_POST['mac']))) {
+ $input_errors[] = "A valid MAC address must be specified.";
+ }
+
+ if (!$input_errors) {
+ $wolent = array();
+ $wolent['interface'] = $_POST['interface'];
+ $wolent['mac'] = $_POST['mac'];
+ $wolent['descr'] = $_POST['descr'];
+
+ if (isset($id) && $a_wol[$id])
+ $a_wol[$id] = $wolent;
+ else
+ $a_wol[] = $wolent;
+
+ write_config();
+
+ header("Location: services_wol.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Services: Wake on LAN: Edit entry");?></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: Wake on LAN: Edit entry</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+ <form action="services_wol_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');
+ for ($i = 1; isset($config['interfaces']['opt' . $i]); $i++) {
+ if (isset($config['interfaces']['opt' . $i]['enable']) &&
+ !$config['interfaces']['opt' . $i]['bridge'])
+ $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 host is connected to.</span></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="20" value="<?=htmlspecialchars($pconfig['mac']);?>">
+ <br>
+ <span class="vexpl">Enter a MAC address in the following format:
+ xx:xx:xx:xx:xx:xx<em></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_wol[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status.php b/usr/local/www/status.php
new file mode 100755
index 0000000..0b54797
--- /dev/null
+++ b/usr/local/www/status.php
@@ -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("pfctl -s nat ", "/sbin/pfctl -s nat");
+defCmdT("pfctl -s rules", "/sbin/pfctl -s rules");
+defCmdT("pfctl -s all"," /sbin/pfctl -s all");
+
+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/usr/local/www/status_captiveportal.php b/usr/local/www/status_captiveportal.php
new file mode 100755
index 0000000..80f2eff
--- /dev/null
+++ b/usr/local/www/status_captiveportal.php
@@ -0,0 +1,128 @@
+#!/usr/local/bin/php
+<?php
+/*
+ status_captiveportal.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><?=gentitle("Status: Captive portal");?></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: Captive portal</p>
+<?php
+
+if ($_GET['act'] == "del") {
+ captiveportal_disconnect_client($_GET['id']);
+}
+
+flush();
+
+function clientcmp($a, $b) {
+ global $order;
+ return strcmp($a[$order], $b[$order]);
+}
+
+$cpdb = array();
+captiveportal_lock();
+$fp = @fopen("{$g['vardb_path']}/captiveportal.db","r");
+
+if ($fp) {
+ while (!feof($fp)) {
+ $line = trim(fgets($fp));
+ if ($line) {
+ $cpent = explode(",", $line);
+ if ($_GET['showact'])
+ $cpent[4] = captiveportal_get_last_activity($cpent[1]);
+ $cpdb[] = $cpent;
+ }
+ }
+
+ fclose($fp);
+
+ if ($_GET['order']) {
+ if ($_GET['order'] == "ip")
+ $order = 2;
+ else if ($_GET['order'] == "mac")
+ $order = 3;
+ else if ($_GET['order'] == "lastact")
+ $order = 4;
+ else
+ $order = 0;
+ usort($cpdb, "clientcmp");
+ }
+}
+captiveportal_unlock();
+?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr"><a href="?order=ip&showact=<?=$_GET['showact'];?>">IP address</a></td>
+ <td class="listhdrr"><a href="?order=mac&showact=<?=$_GET['showact'];?>">MAC address</a></td>
+ <?php if ($_GET['showact']): ?>
+ <td class="listhdrr"><a href="?order=start&showact=<?=$_GET['showact'];?>">Session start</a></td>
+ <td class="listhdr"><a href="?order=lastact&showact=<?=$_GET['showact'];?>">Last activity</a></td>
+ <?php else: ?>
+ <td class="listhdr"><a href="?order=start&showact=<?=$_GET['showact'];?>">Session start</a></td>
+ <?php endif; ?>
+ <td class="list"></td>
+ </tr>
+<?php foreach ($cpdb as $cpent): ?>
+ <tr>
+ <td class="listlr"><?=$cpent[2];?></td>
+ <td class="listr"><?=$cpent[3];?>&nbsp;</td>
+ <td class="listr"><?=htmlspecialchars(date("m/d/Y H:i:s", $cpent[0]));?></td>
+ <?php if ($_GET['showact']): ?>
+ <td class="listr"><?php if ($cpent[4]) echo htmlspecialchars(date("m/d/Y H:i:s", $cpent[4]));?></td>
+ <?php endif; ?>
+ <td valign="middle" class="list" nowrap>
+ <a href="?order=<?=$_GET['order'];?>&showact=<?=$_GET['showact'];?>&act=del&id=<?=$cpent[1];?>" onclick="return confirm('Do you really want to disconnect this client?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+<?php endforeach; ?>
+</table>
+<p>
+<form action="status_captiveportal.php" method="GET">
+<input type="hidden" name="order" value="<?=$_GET['order'];?>">
+<?php if ($_GET['showact']): ?>
+<input type="hidden" name="showact" value="0">
+<input type="submit" class="formbtn" value="Don't show last activity">
+<?php else: ?>
+<input type="hidden" name="showact" value="1">
+<input type="submit" class="formbtn" value="Show last activity">
+<?php endif; ?>
+</form>
+</p>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status_graph.php b/usr/local/www/status_graph.php
new file mode 100755
index 0000000..15330fd
--- /dev/null
+++ b/usr/local/www/status_graph.php
@@ -0,0 +1,80 @@
+#!/usr/local/bin/php
+<?php
+/*
+ status_graph.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");
+
+$curif = "wan";
+if ($_GET['if'])
+ $curif = $_GET['if'];
+
+if ($curif == "wan")
+ $ifnum = get_real_wan_interface();
+else
+ $ifnum = $config['interfaces'][$curif]['if'];
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("Status: Traffic graph");?></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: Traffic graph</p>
+<?php
+$ifdescrs = array('wan' => 'WAN', 'lan' => 'LAN');
+
+for ($j = 1; isset($config['interfaces']['opt' . $j]); $j++) {
+ $ifdescrs['opt' . $j] = $config['interfaces']['opt' . $j]['descr'];
+}
+?>
+<form name="form1" action="" method="get" style="padding-bottom: 10px; margin-bottom: 14px; border-bottom: 1px solid #999999">
+Interface:
+<select name="if" class="formfld" onchange="document.form1.submit()">
+<?php
+foreach ($ifdescrs as $ifn => $ifd) {
+ echo "<option value=\"$ifn\"";
+ if ($ifn == $curif) echo " selected";
+ echo ">" . htmlspecialchars($ifd) . "</option>\n";
+}
+?>
+</select>
+</form>
+<div align="center">
+<embed src="graph.php?ifnum=<?=$ifnum;?>&ifname=<?=rawurlencode($ifdescrs[$curif]);?>" type="image/svg+xml"
+ width="550" height="275" pluginspage="http://www.adobe.com/svg/viewer/install/auto" />
+</div>
+<p><span class="red"><strong>Note:</strong></span> the <a href="http://www.adobe.com/svg/viewer/install/" target="_blank">Adobe SVG viewer</a> is required to view the graph.
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status_interfaces.php b/usr/local/www/status_interfaces.php
new file mode 100755
index 0000000..480312b
--- /dev/null
+++ b/usr/local/www/status_interfaces.php
@@ -0,0 +1,283 @@
+#!/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']) && (!strstr($ifinfo['if'],'tun'))) {
+ $ifinfo['macaddr'] = $linkinfo[3];
+ $ifinfo['inpkts'] = $linkinfo[4];
+ $ifinfo['inerrs'] = $linkinfo[5];
+ $ifinfo['inbytes'] = $linkinfo[6];
+ $ifinfo['outpkts'] = $linkinfo[7];
+ $ifinfo['outerrs'] = $linkinfo[8];
+ $ifinfo['outbytes'] = $linkinfo[9];
+ $ifinfo['collisions'] = $linkinfo[10];
+ } 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];
+ } else if (preg_match("/media: Ethernet (.*)/", $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];
+ }
+ }
+
+ /* get pppoe link status for dial on demand */
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ $ifinfo['pppoelink'] = "up";
+
+ foreach ($ifconfiginfo as $ici) {
+ if (strpos($ici, 'LINK0') !== false)
+ $ifinfo['pppoelink'] = "down";
+ }
+ }
+
+ /* get ppptp link status for dial on demand */
+ if (($ifdescr == "wan") && ($config['interfaces']['wan']['ipaddr'] == "pptp")) {
+
+ unset($ifconfiginfo);
+ exec("/sbin/ifconfig " . $ifinfo['if'], $ifconfiginfo);
+
+ $ifinfo['pptplink'] = "up";
+
+ foreach ($ifconfiginfo as $ici) {
+ if (strpos($ici, 'LINK0') !== false)
+ $ifinfo['pptplink'] = "down";
+ }
+ }
+ }
+
+ return $ifinfo;
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("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['pppoelink']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">PPPoE</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['pppoelink']);?>
+ </td>
+ </tr><?php endif; if ($ifinfo['pptplink']): ?>
+ <tr>
+ <td width="22%" class="listhdrr">PPTP</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['pptplink']);?>
+ </td>
+ </tr><?php endif; 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 if (isset($ifinfo['inerrs'])): ?>
+ <tr>
+ <td width="22%" class="listhdrr">In/out errors</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['inerrs'] . "/" . $ifinfo['outerrs']);?>
+ </td>
+ </tr><?php endif; ?><?php if (isset($ifinfo['collisions'])): ?>
+ <tr>
+ <td width="22%" class="listhdrr">Collisions</td>
+ <td width="78%" class="listr">
+ <?=htmlspecialchars($ifinfo['collisions']);?>
+ </td>
+ </tr><?php endif; ?>
+ <?php endif; ?>
+ <?php $i++; endforeach; ?>
+ </table>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/status_wireless.php b/usr/local/www/status_wireless.php
new file mode 100755
index 0000000..c87c8d6
--- /dev/null
+++ b/usr/local/www/status_wireless.php
@@ -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><?=gentitle("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 (SSID &quot;<?=htmlspecialchars($config['interfaces'][$ifdescr]['wireless']['ssid']);?>&quot;)</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/usr/local/www/system.php b/usr/local/www/system.php
new file mode 100755
index 0000000..90e9502
--- /dev/null
+++ b/usr/local/www/system.php
@@ -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><?=gentitle("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($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/PPP
+ on WAN</strong><br>
+ If this option is set, m0n0wall will use DNS servers assigned
+ by a DHCP/PPP 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/usr/local/www/system_advanced.php b/usr/local/www/system_advanced.php
new file mode 100755
index 0000000..dbc665a
--- /dev/null
+++ b/usr/local/www/system_advanced.php
@@ -0,0 +1,289 @@
+#!/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']);
+$pconfig['disablefirmwarecheck'] = isset($config['system']['disablefirmwarecheck']);
+$pconfig['expanddiags'] = isset($config['system']['webgui']['expanddiags']);
+if ($g['platform'] == "generic-pc")
+ $pconfig['harddiskstandby'] = $config['system']['harddiskstandby'];
+$pconfig['noantilockout'] = isset($config['system']['webgui']['noantilockout']);
+$pconfig['tcpidletimeout'] = $config['filter']['tcpidletimeout'];
+
+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['tcpidletimeout'] && !is_numericint($_POST['tcpidletimeout'])) {
+ $input_errors[] = "The TCP idle timeout must be an integer.";
+ }
+ 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;
+ $config['system']['disablefirmwarecheck'] = $_POST['disablefirmwarecheck'] ? true : false;
+ $config['system']['webgui']['expanddiags'] = $_POST['expanddiags'] ? true : false;
+ if ($g['platform'] == "generic-pc") {
+ $oldharddiskstandby = $config['system']['harddiskstandby'];
+ $config['system']['harddiskstandby'] = $_POST['harddiskstandby'];
+ }
+ $config['system']['webgui']['noantilockout'] = $_POST['noantilockout'] ? true : false;
+ $config['filter']['tcpidletimeout'] = $_POST['tcpidletimeout'];
+
+ write_config();
+
+ if (($config['system']['webgui']['certificate'] != $oldcert)
+ || ($config['system']['webgui']['private-key'] != $oldkey)) {
+ touch($d_sysrebootreqd_path);
+ } else if (($g['platform'] == "generic-pc") && ($config['system']['harddiskstandby'] != $oldharddiskstandby)) {
+ if (!$config['system']['harddiskstandby']) {
+ // Reboot needed to deactivate standby due to a stupid ATA-protocol
+ touch($d_sysrebootreqd_path);
+ unset($config['system']['harddiskstandby']);
+ } else {
+ // No need to set the standby-time if a reboot is needed anyway
+ system_set_harddisk_standby();
+ }
+ }
+
+ $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><?=gentitle("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($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="vncell">&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="vncell">&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="vncell">Console menu </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 valign="top" class="vncell">Firmware version check </td>
+ <td class="vtable">
+ <input name="disablefirmwarecheck" type="checkbox" id="disablefirmwarecheck" value="yes" <?php if ($pconfig['disablefirmwarecheck']) echo "checked"; ?>>
+ <strong>Disable firmware version check</strong><span class="vexpl"><br>
+ This will cause m0n0wall not to check for newer firmware versions when the <a href="system_firmware.php">System: Firmware</a> page is viewed.</span></td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncell">TCP idle timeout </td>
+ <td class="vtable"> <span class="vexpl">
+ <input name="tcpidletimeout" type="text" class="formfld" id="tcpidletimeout" size="8" value="<?=htmlspecialchars($pconfig['tcpidletimeout']);?>">
+ seconds<br>
+ Idle TCP connections will be removed from the state table after no packets have been received for the specified number of seconds. Don't set this too high or your state table could become full of connections that have been improperly shut down. The default is 2.5 hours.</span></td>
+ </tr>
+<?php if ($g['platform'] == "generic-pc"): ?>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Hard disk standby time </td>
+ <td width="78%" class="vtable">
+ <select name="harddiskstandby" class="formfld">
+ <?php
+ /* Values from ATA-2
+ http://www.t13.org/project/d0948r3-ATA-2.pdf
+ Page 66 */
+ $sbvals = explode(" ", "0.5,6 1,12 2,24 3,36 4,48 5,60 7.5,90 10,120 15,180 20,240 30,241 60,242");
+ ?>
+ <option value="" <?php if(!$pconfig['harddiskstandby']) echo('selected');?>>Always on</option>
+ <?php
+ foreach ($sbvals as $sbval):
+ list($min,$val) = explode(",", $sbval); ?>
+ <option value="<?=$val;?>" <?php if($pconfig['harddiskstandby'] == $val) echo('selected');?>><?=$min;?> minutes</option>
+ <?php endforeach; ?>
+ </select>
+ <br>
+ Puts the hard disk into standby mode when the selected amount of time after the last
+ access has elapsed. <em>Do not set this for CF cards.</em></td>
+ </tr>
+<?php endif; ?>
+ <tr>
+ <td width="22%" valign="top" class="vncell">Navigation</td>
+ <td width="78%" class="vtable">
+ <input name="expanddiags" type="checkbox" id="expanddiags" value="yes" <?php if ($pconfig['expanddiags']) echo "checked"; ?>>
+ <strong>Keep diagnostics in navigation expanded </strong></td>
+ </tr>
+ <tr>
+ <td width="22%" valign="top" class="vncell">webGUI anti-lockout</td>
+ <td width="78%" class="vtable">
+ <input name="noantilockout" type="checkbox" id="noantilockout" value="yes" <?php if ($pconfig['noantilockout']) echo "checked"; ?>>
+ <strong>Disable webGUI anti-lockout rule</strong><br>
+ By default, access to the webGUI on the LAN interface is always permitted, regardless of the user-defined filter rule set. Enable this feature to control webGUI access (make sure to have a filter rule in place that allows you in, or you will lock yourself out!).<br>
+ Hint:
+ the &quot;set LAN IP address&quot; option in the console menu resets this setting as well.</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/usr/local/www/system_firmware.php b/usr/local/www/system_firmware.php
new file mode 100755
index 0000000..e008813
--- /dev/null
+++ b/usr/local/www/system_firmware.php
@@ -0,0 +1,206 @@
+#!/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 if (!file_exists($_FILES['ulfile']['tmp_name'])) {
+ /* probably out of memory for the MFS */
+ $input_errors[] = "Image upload failed (out of memory?)";
+ exec_rc_script("/etc/rc.firmware disable");
+ if (file_exists($d_fwupenabled_path))
+ unlink($d_fwupenabled_path);
+ } 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 {
+ if (!isset($config['system']['disablefirmwarecheck']))
+ $fwinfo = check_firmware_version();
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("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($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/usr/local/www/system_routes.php b/usr/local/www/system_routes.php
new file mode 100755
index 0000000..c4abdff
--- /dev/null
+++ b/usr/local/www/system_routes.php
@@ -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><?=gentitle("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($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', 'wan' => 'WAN', '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/usr/local/www/system_routes_edit.php b/usr/local/www/system_routes_edit.php
new file mode 100755
index 0000000..826a5f1
--- /dev/null
+++ b/usr/local/www/system_routes_edit.php
@@ -0,0 +1,176 @@
+#!/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><?=gentitle("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); ?>
+ <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', '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 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/usr/local/www/vpn_ipsec.php b/usr/local/www/vpn_ipsec.php
new file mode 100755
index 0000000..cea915a
--- /dev/null
+++ b/usr/local/www/vpn_ipsec.php
@@ -0,0 +1,192 @@
+#!/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><?=gentitle("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($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>
+ <ul id="tabnav">
+ <li class="tabact">Tunnels</li>
+ <li class="tabinact"><a href="vpn_ipsec_mobile.php">Mobile clients</a></li>
+ <li class="tabinact"><a href="vpn_ipsec_keys.php">Pre-shared keys</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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/usr/local/www/vpn_ipsec_edit.php b/usr/local/www/vpn_ipsec_edit.php
new file mode 100755
index 0000000..f0fafde
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_edit.php
@@ -0,0 +1,527 @@
+#!/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 (is_null($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']);
+ $pconfig['auto'] = isset($a_ipsec[$id]['auto']);
+
+ 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'];
+ } else if (isset($a_ipsec[$id]['p1']['myident']['ufqdn'])) {
+ $pconfig['p1myidentt'] = 'user_fqdn';
+ $pconfig['p1myident'] = $a_ipsec[$id]['p1']['myident']['ufqdn'];
+ }
+
+ $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'] = "sha1";
+ $pconfig['p1dhgroup'] = "2";
+ $pconfig['p2proto'] = "esp";
+ $pconfig['p2ealgos'] = explode(",", "3des,blowfish,cast128,rijndael");
+ $pconfig['p2halgos'] = explode(",", "hmac_sha1,hmac_md5");
+ $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'] == "user_fqdn") {
+ $ufqdn = explode("@",$_POST['p1myident']);
+ if (!is_domain($ufqdn[1]))
+ $input_errors[] = "A valid User FQDN in the form of user@my.domain.com for 'My identifier' must be specified.";
+ }
+
+ if ($_POST['p1myidentt'] == "myaddress")
+ $_POST['p1myident'] = "";
+
+ if (!$input_errors) {
+ $ipsecent['disabled'] = $_POST['disabled'] ? true : false;
+ $ipsecent['auto'] = $_POST['auto'] ? 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;
+ case 'user_fqdn':
+ $ipsecent['p1']['myident']['ufqdn'] = $_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><?=gentitle("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); ?>
+ <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">Auto-establish</td>
+ <td width="78%" class="vtable">
+ <input name="auto" type="checkbox" id="auto" value="yes" <?php if ($pconfig['auto']) echo "checked"; ?>>
+ <strong>Automatically establish this tunnel</strong><br>
+ <span class="vexpl">Set this option to automatically re-establish this tunnel after reboots/reconfigures. If this is not set, the tunnel is established on demand.</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="<?=htmlspecialchars($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; ?>
+ </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/usr/local/www/vpn_ipsec_keys.php b/usr/local/www/vpn_ipsec_keys.php
new file mode 100755
index 0000000..f0a9330
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_keys.php
@@ -0,0 +1,107 @@
+#!/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><?=gentitle("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($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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_ipsec.php">Tunnels</a></li>
+ <li class="tabinact"><a href="vpn_ipsec_mobile.php">Mobile clients</a></li>
+ <li class="tabact">Pre-shared keys</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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/usr/local/www/vpn_ipsec_keys_edit.php b/usr/local/www/vpn_ipsec_keys_edit.php
new file mode 100755
index 0000000..8fe589e
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_keys_edit.php
@@ -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><?=gentitle("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="<?=htmlspecialchars($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/usr/local/www/vpn_ipsec_mobile.php b/usr/local/www/vpn_ipsec_mobile.php
new file mode 100755
index 0000000..3031a45
--- /dev/null
+++ b/usr/local/www/vpn_ipsec_mobile.php
@@ -0,0 +1,330 @@
+#!/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'] = "sha1";
+ $pconfig['p1dhgroup'] = "2";
+ $pconfig['p2proto'] = "esp";
+ $pconfig['p2ealgos'] = explode(",", "3des,blowfish,cast128,rijndael");
+ $pconfig['p2halgos'] = explode(",", "hmac_sha1,hmac_md5");
+ $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'];
+ } else if (isset($a_ipsec['p1']['myident']['ufqdn'])) {
+ $pconfig['p1myidentt'] = 'user_fqdn';
+ $pconfig['p1myident'] = $a_ipsec['p1']['myident']['ufqdn'];
+ }
+
+ $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'] == "user_fqdn") {
+ $ufqdn = explode("@",$_POST['p1myident']);
+ if (!is_domain($ufqdn[1]))
+ $input_errors[] = "A valid User FQDN in the form of user@my.domain.com 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;
+ case 'user_fqdn':
+ $ipsecent['p1']['myident']['ufqdn'] = $_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><?=gentitle("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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_ipsec.php">Tunnels</a></li>
+ <li class="tabact">Mobile clients</li>
+ <li class="tabinact"><a href="vpn_ipsec_keys.php">Pre-shared keys</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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; ?>
+ </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/usr/local/www/vpn_openvpn.php b/usr/local/www/vpn_openvpn.php
new file mode 100755
index 0000000..6fd3e1e
--- /dev/null
+++ b/usr/local/www/vpn_openvpn.php
@@ -0,0 +1,366 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ 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");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['server'])){
+ $config['ovpn']['server'] = array();
+ $config['ovpn']['server']['tun_iface'] = "tun0";
+ $config['ovpn']['server']['psh_options'] = array();
+ /* Initialise with some sensible defaults */
+ $config['ovpn']['server']['port'] = 5000;
+ $config['ovpn']['server']['proto'] = 'UDP';
+ $config['ovpn']['server']['maxcli'] = 25;
+ $config['ovpn']['server']['crypto'] = 'BF-CBC';
+ $config['ovpn']['server']['dupcn'] = true;
+ $config['ovpn']['server']['verb'] = 1;
+}
+
+if ($_POST) {
+
+ unset($input_errors);
+
+ /* input validation */
+ if ($_POST['enable']) {
+ $reqdfields = explode(" ", "tun_iface bind_iface ipblock");
+ $reqdfieldsn = explode(",", "Tunnel type,Interface binding,IP address block start");
+
+ do_input_validation($_POST, $reqdfields, $reqdfieldsn, &$input_errors);
+
+ }
+
+ /* need a test here to make sure prefix and max_clients are coherent */
+
+ /* Sort out the cert+key files */
+ if (is_null($_POST['ca_cert']))
+ $input_errors[] = "You must provide a CA certificate file";
+ elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The CA certificate does not appear to be valid.";
+
+ if (is_null($_POST['srv_cert']))
+ $input_errors[] = "You must provide a server certificate file";
+ elseif (!strstr($_POST['srv_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['srv_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The server certificate does not appear to be valid.";
+
+ if (is_null($_POST['srv_key']))
+ $input_errors[] = "You must provide a server key file";
+ elseif (!strstr($_POST['srv_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['srv_key'], "END RSA PRIVATE KEY"))
+ $input_errors[] = "The server key does not appear to be valid.";
+
+ if (is_null($_POST['dh_param']))
+ $input_errors[] = "You must provide a DH parameters file";
+ elseif (!strstr($_POST['dh_param'], "BEGIN DH PARAMETERS") || !strstr($_POST['dh_param'], "END DH PARAMETERS"))
+ $input_errors[] = "The DH parameters do not appear to be valid.";
+
+ if (!$input_errors) {
+ $server =& $config['ovpn']['server'];
+ $server['enable'] = $_POST['enable'] ? true : false;
+
+ /* Make sure that the tunnel interface type has not changed */
+ if ($server['tun_iface'] != $_POST['tun_iface']){
+ $server['tun_iface'] = $_POST['tun_iface'];
+ touch($d_sysrebootreqd_path);
+ }
+
+ $server['bind_iface'] = $_POST['bind_iface'];
+ $server['port'] = $_POST['port'];
+ $server['proto'] = $_POST['proto'];
+
+ /* Make sure the IP address and/or prefix have not changed */
+ if ($server['ipblock'] != $_POST['ipblock']){
+ $server['ipblock'] = $_POST['ipblock'];
+ touch($d_sysrebootreqd_path);
+ }
+ if ($server['prefix'] != $_POST['prefix']){
+ $server['prefix'] = $_POST['prefix'];
+ touch($d_sysrebootreqd_path);
+ }
+
+ $server['maxcli'] = $_POST['maxcli'];
+ $server['crypto'] = $_POST['crypto'];
+ $server['cli2cli'] = $_POST['cli2cli'] ? true : false;
+ $server['dupcn'] = $_POST['dupcn'] ? true : false;
+ $server['psh_options']['redir'] = $_POST['psh_redir'] ? true : false;
+ $server['psh_options']['redir_loc'] = $_POST['psh_redir_loc'] ? true : false;
+ if ($_POST['psh_rtedelay'])
+ $server['psh_options']['rtedelay'] = $_POST['psh_rtedelay_int'];
+ if ($_POST['psh_ping'])
+ $server['psh_options']['ping'] = $_POST['psh_ping_int'];
+ if ($_POST['psh_pingexit'])
+ $server['psh_options']['pingexit'] = $_POST['psh_pingexit_int'];
+ if ($_POST['psh_pingrst'])
+ $server['psh_options']['pingrst'] = $_POST['psh_pingrst_int'];
+ if ($_POST['inact'])
+ $server['psh_options']['inact'] = $_POST['psh_inact_int'];
+ $server['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $server['srv_cert'] = base64_encode($_POST['srv_cert']);
+ $server['srv_key'] = base64_encode($_POST['srv_key']);
+ $server['dh_param'] = base64_encode($_POST['dh_param']);
+
+ write_config();
+
+ $retval = 0;
+ if (file_exists($d_sysrebootreqd_path)) {
+ /* Rewrite interface definitions */
+ $retval = ovpn_server_iface();
+ }
+ else{
+ ovpn_lock();
+ $retval = ovpn_config_server();
+ ovpn_unlock();
+ }
+ $savemsg = get_std_save_message($retval);
+ }
+}
+
+/* Simply take a copy of the array */
+$pconfig = $config['ovpn']['server'];
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: OpenVPN");?></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: OpenVPN</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="vpn_openvpn.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Server</li>
+ <li class="tabinact"><a href="vpn_openvpn_cli.php">Client</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+&nbsp; <br>
+ </span></strong><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 (isset($pconfig['enable'])) echo "checked"; ?>>
+ <strong>Enable OpenVPN server </strong></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Tunnel type</td>
+ <td width="78%" class="vtable">
+ <input type="radio" name="tun_iface" class="formfld" value="tun0" <?php if ($pconfig['tun_iface'] == 'tun0') echo "checked"; ?>>
+ TUN&nbsp;
+ <input type="radio" name="tun_iface" class="formfld" value="tap0" <?php if ($pconfig['tun_iface'] == 'tap0') echo "checked"; ?>>
+ TAP
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">OpenVPN protocol/port</td>
+ <td width="78%" class="vtable">
+ <input type="radio" name="proto" class="formfld" value="UDP" <?php if ($pconfig['proto'] == 'UDP') echo "checked"; ?>>
+ UDP&nbsp;
+ <input type="radio" name="proto" class="formfld" value="TCP" <?php if ($pconfig['proto'] == 'TCP') echo "checked"; ?>>
+ TCP<br><br>
+ Port:
+ <input name="port" type="text" class="formfld" size="5" maxlength="5" value="<?= $pconfig['port']; ?>"><br>
+ Enter the port number to use for the server (default is 5000).</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Interface binding</td>
+ <td width="78%" class="vtable">
+ <select name="bind_iface" class="formfld">
+ <?php
+ $interfaces = ovpn_real_interface_list();
+ foreach ($interfaces as $key => $iface):
+ ?>
+ <option value="<?=$key;?>" <?php if ($key == $pconfig['bind_iface']) echo "selected"; ?>> <?= $iface;?>
+ </option>
+ <?php endforeach;?>
+ </select>
+ <span class="vexpl"><br>
+ Choose an interface for the OpenVPN server to listen on.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">IP address block</td>
+ <td width="78%" class="vtable">
+ <input name="ipblock" type="text" class="formfld" size="20" value="<?=htmlspecialchars($pconfig['ipblock']);?>">
+ /
+ <select name="prefix" class="formfld">
+ <?php for ($i = 29; $i > 19; $i--): ?>
+ <option value="<?=$i;?>" <?php if ($i == $pconfig['prefix']) echo "selected"; ?>>
+ <?=$i;?>
+ </option>
+ <?php endfor; ?>
+ </select>
+ <br>
+ Enter the IP address block for the OpenVPN server and clients to use.<br>
+ <br>
+ Maximum number of simultaneous clients:
+ <input name="maxcli" type="text" class="formfld" size="3" maxlength="3" value="<?=htmlspecialchars($pconfig['maxcli']);?>">
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">CA certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="ca_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['ca_cert']));?></textarea>
+ <br>
+ Paste a CA certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Server certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="srv_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_cert']));?></textarea>
+ <br>
+ Paste a server certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Server key</td>
+ <td width="78%" class="vtable">
+ <textarea name="srv_key" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['srv_key']));?></textarea>
+ <br>Paste the server RSA private key here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">DH parameters</td>
+ <td width="78%" class="vtable">
+ <textarea name="dh_param" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['dh_param']));?></textarea>
+ <br>
+ Paste the Diffie-Hellman parameters in PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Crypto</td>
+ <td width="78%" class="vtable">
+ <select name="crypto" class="formfld">
+ <?php $cipher_list = ovpn_get_cipher_list();
+ foreach($cipher_list as $key => $value){
+ ?>
+ <option value="<?= $key ?>" <?php if ($pconfig['crypto'] == $key) echo "selected"; ?>>
+ <?= $value ?>
+ </option>
+ <?php
+ }
+ ?>
+ </select>
+ <br>
+ Select a data channel encryption cipher.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Internal routing mode</td>
+ <td width="78%" class="vtable">
+ <input name="cli2cli" type="checkbox" value="yes" <?php if (isset($pconfig['cli2cli'])) echo "checked"; ?>>
+ <strong>Enable client-to-client routing</strong><br>
+ If this option is on, clients are allowed to talk to each other.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client authentication</td>
+ <td width="78%" class="vtable">
+ <input name="dupcn" type="checkbox" value="yes" <?php if (isset($pconfig['dupcn'])) echo "checked"; ?>>
+ <strong>Permit duplicate client certificates</strong><br>
+ If this option is on, clients with duplicate certificates will not be disconnected.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Client-push options</td>
+ <td width="78%" class="vtable">
+ <table border="0" cellspacing="0" cellpadding="0">
+ <tr>
+ <td><input type="checkbox" name="psh_redir" value="yes" <?php if (isset($pconfig['psh_options']['redir'])) echo "checked"; ?>>
+ Redirect-gateway</td>
+ <td>&nbsp;</td>
+ <td><input type="checkbox" name="psh_redir_loc" value="yes" <?php if (isset($pconfig['psh_options']['redir_loc'])) echo "checked"; ?>>
+ Local</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_rtedelay" value="yes" <?php if (isset($pconfig['psh_options']['rtedelay'])) echo "checked"; ?>> Route-delay</td>
+ <td width="16">&nbsp;</td>
+ <td><input type="text" name="psh_rtedelay_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['rtedelay']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_inact" value="yes" <?php if (isset($pconfig['psh_options']['inact'])) echo "checked"; ?>>
+ Inactive</td>
+ <td>&nbsp;</td>
+ <td><input type="text" name="psh_inact_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['inact']?>">
+ seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_ping" value="yes" <?php if (isset($pconfig['psh_options']['ping'])) echo "checked"; ?>> Ping</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_ping_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['ping']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingexit" value="yes" <?php if (isset($pconfig['psh_options']['pingexit'])) echo "checked"; ?>> Ping-exit</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingexit_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingexit']?>"> seconds</td>
+ </tr>
+ <tr>
+ <td><input type="checkbox" name="psh_pingrst" value="yes" <?php if (isset($pconfig['psh_options']['pingrst'])) echo "checked"; ?>> Ping-restart</td>
+ <td>&nbsp;</td>
+ <td>Interval: <input type="text" name="psh_pingrst_int" class="formfld" size="4" value="<?= $pconfig['psh_options']['pingrst']?>"> seconds</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>Note:<br>
+ </strong></span>Changing any settings on this page will disconnect all clients!</span>
+ </td>
+ </tr>
+ </table> </td>
+</tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_openvpn_cli.php b/usr/local/www/vpn_openvpn_cli.php
new file mode 100755
index 0000000..3bd3d93
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_cli.php
@@ -0,0 +1,148 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_cli.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ 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");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['client'])){
+ $config['ovpn']['client'] = array();
+ $config['ovpn']['client']['tunnel'] = array();
+}
+
+$ovpncli =& $config['ovpn']['client']['tunnel'];
+
+if ($_POST['apply']) {
+ $retval = 0;
+ if (file_exists($d_sysrebootreqd_path)) {
+ /* Rewrite interface definitions */
+ $retval = ovpn_client_iface();
+ }
+ else{
+ ovpn_lock();
+ $retval = ovpn_config_client();
+ ovpn_unlock();
+ }
+ if (file_exists($d_ovpnclidirty_path))
+ unlink($d_ovpnclidirty_path);
+ $savemsg = get_std_save_message($retval);
+}
+
+if ($_GET['act'] == "del") {
+ if ($ovpncli[$_GET['id']]) {
+ unset($ovpncli[$_GET['id']]);
+ write_config();
+ ovpn_client_kill($_GET['id']);
+ touch($d_ovpnclidirty_path);
+ header("Location: vpn_openvpn_cli.php");
+ exit;
+ }
+}
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: OpenVPN");?></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: OpenVPN</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if (file_exists($d_sysrebootreqd_path) && !file_exists($d_ovpnclidirty_path)) print_info_box(get_std_save_message(0)); ?>
+<form action="vpn_openvpn_cli.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+<?php if (file_exists($d_ovpnclidirty_path)): ?><p>
+<?php print_info_box_np("The OpenVPN client 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>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_openvpn.php">Server</a></li>
+ <li class="tabact">Client</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td class="tabcont">
+ <strong><span class="red">WARNING: This feature is experimental and modifies your optional interface configuration.
+ Backup your configuration before using OpenVPN, and restore it before upgrading.<br>
+&nbsp; <br>
+ </span></strong>
+ <table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td width="10%" class="listhdrr">Interface</td>
+ <td width="30%" class="listhdrr">Server address</td>
+ <td width="10%" class="listhdrr" align="middle">Version</td>
+ <td width="40%" class="listhdr">Description</td>
+ <td width="10%" class="list"></td>
+ </tr>
+
+ <?php $i = 0; foreach ($ovpncli as $client):
+ if (!isset($client['enable'])) {
+ $spans = "<span class=\"gray\">";
+ $spane = "</span>";
+ } else {
+ $spans = $spane = "";
+ }
+ ?>
+
+ <tr>
+ <td class="listlr"><?=$spans;?>
+ <?= $client['if'].":".$client['cport'];?>
+ <?=$spane;?></td>
+ <td class="listr"><?=$spans;?>
+ <?= $client['saddr'].":".$client['sport'];?>
+ <?=$spane;?></td>
+ <td align="middle" class="listr"><?=$spans;?>
+ <?= $client['ver'];?>
+ <?=$spane;?></td>
+ <td class="listbg"><?=$spans;?>
+ <?= $client['descr'];?>
+ <?=$spane;?></td>
+ <td valign="middle" nowrap class="list"> <a href="vpn_openvpn_cli_edit.php?id=<?=$i;?>"><img src="e.gif" width="17" height="17" border="0"></a>
+ &nbsp;<a href="vpn_openvpn_cli.php?act=del&id=<?=$i;?>" onclick="return confirm('Do you really want to delete this client configuration?')"><img src="x.gif" width="17" height="17" border="0"></a></td>
+ </tr>
+ <?php $i++; endforeach; ?>
+ <tr>
+ <td class="list" colspan="4">&nbsp;</td>
+ <td class="list"> <a href="vpn_openvpn_cli_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/usr/local/www/vpn_openvpn_cli_edit.php b/usr/local/www/vpn_openvpn_cli_edit.php
new file mode 100755
index 0000000..4c27709
--- /dev/null
+++ b/usr/local/www/vpn_openvpn_cli_edit.php
@@ -0,0 +1,353 @@
+#!/usr/local/bin/php
+<?php
+/*
+ vpn_openvpn_cli_edit.php
+
+ Copyright (C) 2004 Peter Curran (peter@closeconsultants.com).
+ 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");
+require_once("openvpn.inc");
+
+if (!is_array($config['ovpn']))
+ $config['ovpn'] = array();
+if (!is_array($config['ovpn']['client'])){
+ $config['ovpn']['client'] = array();
+ $config['ovpn']['client']['tunnel'] = array();
+}
+
+function getnxt_if($type) {
+ /* find the first available device of type $type */
+ global $config;
+ $a_client = $config['ovpn']['client']['tunnel'];
+ $max = ($type == 'tun') ? 17 : 4;
+ for ($i = 1; $i < $max ; $i++) {
+ $hit = false;
+ foreach ($a_client as $client) {
+ if ($client['iface'] == $type . $i) {
+ $hit = true;
+ break;
+ }
+ }
+ if (!$hit)
+ return $type . $i;
+ }
+ return false;
+}
+
+
+function getnxt_port() {
+ /* Get first unused port */
+ global $config;
+ $a_client = $config['ovpn']['client']['tunnel'];
+ $port = 5001;
+ while (true) {
+ $hit = false;
+ foreach ($a_client as $client) {
+ if ($client['cport'] == $port) {
+ $hit = true;
+ break;
+ }
+ }
+ if (!$hit)
+ return $port;
+ $port++;
+ }
+ return false; /* should never get here */
+}
+
+
+$ovpncli =& $config['ovpn']['client']['tunnel'];
+
+$id = $_GET['id'];
+if (isset($_POST['id']))
+ $id = $_POST['id'];
+
+if (isset($id) && $ovpncli[$id]) {
+ $pconfig = $config['ovpn']['client']['tunnel'][$id];
+ if (isset($ovpncli[$id]['pull']))
+ $pconfig['pull'] = true;
+}
+else {
+ /* creating - set defaults */
+ $pconfig = array();
+ $pconfig['type'] = 'tun';
+ $pconfig['proto'] = 'udp';
+ $pconfig['sport'] = '5000';
+ $pconfig['ver'] = '2';
+ $pconfig['crypto'] = 'BF-CBC';
+ $pconfig['pull'] = true;
+ $pconfig['enable'] = true;
+}
+
+if (isset($_POST['pull'])) {
+ /* Called from form */
+ unset($input_errors);
+ if (is_null($_POST['ca_cert']))
+ $input_errors[] = "You must provide a CA certificate file";
+ elseif (!strstr($_POST['ca_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['ca_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The CA certificate does not appear to be valid.";
+
+ if (is_null($_POST['cli_cert']))
+ $input_errors[] = "You must provide a client certificate file";
+ elseif (!strstr($_POST['cli_cert'], "BEGIN CERTIFICATE") || !strstr($_POST['cli_cert'], "END CERTIFICATE"))
+ $input_errors[] = "The client certificate does not appear to be valid.";
+
+ if (is_null($_POST['cli_key']))
+ $input_errors[] = "You must provide a client key file";
+ elseif (!strstr($_POST['cli_key'], "BEGIN RSA PRIVATE KEY") || !strstr($_POST['cli_key'], "END RSA PRIVATE KEY"))
+ $input_errors[] = "The client key does not appear to be valid.";
+
+ if (!$input_errors) {
+ if (isset($id)) {
+ /* Editing an existing entry */
+ $ovpnent = $ovpncli[$id];
+ /* Test Server type hasn't changed */
+ if ($ovpnent['type'] != $_POST['type']) {
+ $nxt_if = getnxt_if($_POST['type']);
+ if (!$nxt_if)
+ $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+ else
+ $ovpnent['if'] = $nxt_if;
+ /* Need to reboot in order to create interfaces cleanly */
+ touch($d_sysrebootreqd_path);
+ }
+ /* Has the enable/disable state changed? */
+ if (isset($ovpnent['enable']) && isset($_POST['disabled'])) {
+ touch($d_sysrebootreqd_path);
+ touch($d_ovpnclidirty_path);
+ ovpn_client_kill($id);
+ ovpn_client_iface_del($id);
+ }
+ if (!isset($ovpnent['enable']) && !isset($_POST['disabled'])) {
+ touch($d_sysrebootreqd_path);
+ touch($d_ovpnclidirty_path);
+ }
+ }
+ else {
+ /* Creating a new entry */
+ $ovpnent = array();
+ $nxt_if = getnxt_if($_POST['type']);
+ if (!$nxt_if)
+ $input_errors[] = "Run out of devices for a tunnel of type {$_POST['type']}";
+ else
+ $ovpnent['if'] = $nxt_if;
+ $ovpnent['cport'] = getnxt_port();
+ /* I think we have to reboot to have the interface created cleanly */
+ touch($d_sysrebootreqd_path);
+ }
+ $ovpnent['type'] = $_POST['type'];
+ $ovpnent['proto'] = $_POST['proto'];
+ $ovpnent['sport'] = $_POST['sport'];
+ $ovpnent['ver'] = $_POST['ver'];
+ $ovpnent['saddr'] = $_POST['saddr'];
+ $ovpnent['descr'] = $_POST['descr'];
+ $ovpnent['ca_cert'] = base64_encode($_POST['ca_cert']);
+ $ovpnent['cli_cert'] = base64_encode($_POST['cli_cert']);
+ $ovpnent['cli_key'] = base64_encode($_POST['cli_key']);
+ $ovpnent['crypto'] = $_POST['crypto'];
+ $ovpnent['pull'] = true; //This is a fixed config for this version
+ $ovpnent['enable'] = isset($_POST['disabled']) ? false : true;
+
+
+ if (isset($id) && $ovpncli[$id]){
+ $ovpncli[$id] = $ovpnent;
+ }
+ else{
+ $ovpncli[] = $ovpnent;
+ }
+
+ write_config();
+ touch($d_ovpnclidirty_path);
+ header("Location: vpn_openvpn_cli.php");
+ exit;
+ }
+}
+
+?>
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
+<html>
+<head>
+<title><?=gentitle("VPN: OpenVPN: Edit client");?></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: OpenVPN: Edit client</p>
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+
+<form action="vpn_openvpn_cli_edit.php" method="post" enctype="multipart/form-data" name="iform" id="iform">
+ <table width="100%" border="0" cellpadding="6" cellspacing="0">
+ <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 (!isset($pconfig['enable'])) echo "checked"; ?>>
+ <strong>Disable this client</strong><br>
+ <span class="vexpl">Set this option to disable this client without removing it from the list.</span>
+ </td>
+ </tr>
+
+ <tr>
+ <td colspan="2" class="list" height="12"></td>
+ </tr>
+
+ <tr>
+ <td colspan="2" valign="top" class="listtopic">Server information</td>
+ </tr>
+ <tr>
+ <td valign="top" class="vncellreq">Tunnel type</td>
+ <td class="vtable">
+ <input name="type" type="radio" class="formfld" value="tun" <?php if ($pconfig['type'] == 'tun') echo "checked"; ?>> TUN&nbsp;
+<input name="type" type="radio" class="formfld" value="tap" <?php if ($pconfig['type'] == 'tap') echo "checked"; ?>> TAP</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Tunnel protocol</td>
+ <td width="78%" class="vtable">
+<input name="proto" type="radio" class="formfld" value="udp" <?php if ($pconfig['proto'] == 'udp') echo "checked"; ?>> UDP&nbsp;
+<input name="proto" type="radio" class="formfld" value="tcp" <?php if ($pconfig['proto'] == 'tcp') echo "checked"; ?>> TCP<br>
+ <span class="vexpl">Important: These settings must match the server's configuration.</span></td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Port</td>
+ <td width="78%" class="vtable">
+ <input name="sport" type="text" class="formfld" size="5" maxlength="5" value="<?=htmlspecialchars($pconfig['sport']);?>"><br>
+ Enter the server's port number (default is 5000).</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Address</td>
+ <td width="78%" class="vtable">
+ <input name="saddr" type="text" class="formfld" size="20" maxlength="255" value="<?=htmlspecialchars($pconfig['saddr']);?>">
+ <br>
+ Enter the server's IP address or FQDN.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Version</td>
+ <td width="78%" class="vtable">
+ <input name="ver" type="radio" class="formfld" value="2" <?php if ($pconfig['ver'] == '2') echo "checked"; ?>> 2.0&nbsp;
+ <input name="ver" type="radio" class="formfld" value="1" <?php if ($pconfig['ver'] == '1') echo "checked"; ?>> 1.x
+ <br>
+ Specify which version of the OpenVPN protocol the server runs.</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">Client configuration</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Interface</td>
+ <td width="78%" class="vtable">
+ <strong>Auto</strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Port</td>
+ <td width="78%" class="vtable">
+ <strong>Auto</strong>
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">CA certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="ca_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['ca_cert']));?></textarea>
+ <br>
+ Paste a CA certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Client certificate</td>
+ <td width="78%" class="vtable">
+ <textarea name="cli_cert" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['cli_cert']));?></textarea>
+ <br>
+ Paste a client certificate in X.509 PEM format here.</td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Client key</td>
+ <td width="78%" class="vtable">
+ <textarea name="cli_key" cols="65" rows="4" class="formpre"><?=htmlspecialchars(base64_decode($pconfig['cli_key']));?></textarea>
+ <br>Paste the client RSA private key here.</td>
+ </tr>
+
+
+ <tr>
+ <td width="22%" valign="top" class="vncell">Crypto</td>
+ <td width="78%" class="vtable">
+ <select name="crypto" class="formfld">
+ <?php $cipher_list = ovpn_get_cipher_list();
+ foreach($cipher_list as $key => $value){
+ ?>
+ <option value="<?= $key ?>" <?php if ($pconfig['crypto'] == $key) echo "selected"; ?>>
+ <?= $value ?>
+ </option>
+ <?php
+ }
+ ?>
+ </select>
+ <br>
+ Select the data channel encryption cipher. This must match the setting on the server.
+ </td>
+ </tr>
+
+ <tr>
+ <td width="22%" valign="top" class="vncellreq">Options</td>
+ <td width="78%" class="vtable">
+ <input type="checkbox" name="pull" value="yes" <?php if ($pconfig['pull']) echo "checked"; ?>>
+ Client-pull</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)): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_pptp.php b/usr/local/www/vpn_pptp.php
new file mode 100755
index 0000000..b796639
--- /dev/null
+++ b/usr/local/www/vpn_pptp.php
@@ -0,0 +1,309 @@
+#!/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['radacct_enable'] = isset($pptpcfg['radius']['accounting']);
+$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']['accounting'] = $_POST['radacct_enable'] ? 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><?=gentitle("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.radacct_enable.disabled = 0;
+ document.iform.radiusserver.disabled = 0;
+ document.iform.radiussecret.disabled = 0;
+ } else {
+ document.iform.radacct_enable.disabled = 1;
+ 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.radacct_enable.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>
+<form action="vpn_pptp.php" method="post" name="iform" id="iform">
+<?php if ($input_errors) print_input_errors($input_errors); ?>
+<?php if ($savemsg) print_info_box($savemsg); ?>
+<table width="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabact">Configuration</li>
+ <li class="tabinact"><a href="vpn_pptp_users.php">Users</a></li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td 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="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.<br>
+ <br>
+ <input name="radacct_enable" type="checkbox" id="radacct_enable" onclick="enable_change(false)" value="yes" <?php if ($pconfig['radacct_enable'] == "yes") echo "checked"; ?>>
+ <strong>Enable RADIUS accounting <br>
+ </strong>Sends accounting packets to the RADIUS server. </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>
+ </td>
+ </tr>
+</table>
+</form>
+<script language="JavaScript">
+<!--
+enable_change(false);
+//-->
+</script>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_pptp_users.php b/usr/local/www/vpn_pptp_users.php
new file mode 100755
index 0000000..0122734
--- /dev/null
+++ b/usr/local/www/vpn_pptp_users.php
@@ -0,0 +1,126 @@
+#!/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><?=gentitle("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($savemsg); ?>
+<?php if (isset($config['pptpd']['radius']['enable']))
+ print_info_box("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="100%" border="0" cellpadding="0" cellspacing="0">
+ <tr><td>
+ <ul id="tabnav">
+ <li class="tabinact"><a href="vpn_pptp.php">Configuration</a></li>
+ <li class="tabact">Users</li>
+ </ul>
+ </td></tr>
+ <tr>
+ <td colspan="3" class="tabcont">
+ <table width="80%" border="0" cellpadding="0" cellspacing="0">
+ <tr>
+ <td class="listhdrr">Username</td>
+ <td class="listhdr">IP address</td>
+ <td class="list"></td>
+ </tr>
+ <?php $i = 0; foreach ($a_secret as $secretent): ?>
+ <tr>
+ <td class="listlr">
+ <?=htmlspecialchars($secretent['name']);?>
+ </td>
+ <td class="listr">
+ <?=htmlspecialchars($secretent['ip']);?>&nbsp;
+ </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" colspan="2"></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>
+ </td>
+ </tr>
+</table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/local/www/vpn_pptp_users_edit.php b/usr/local/www/vpn_pptp_users_edit.php
new file mode 100755
index 0000000..1b681ee
--- /dev/null
+++ b/usr/local/www/vpn_pptp_users_edit.php
@@ -0,0 +1,159 @@
+#!/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'];
+ $pconfig['ip'] = $a_secret[$id]['ip'];
+}
+
+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 (($_POST['ip'] && !is_ipaddr($_POST['ip']))) {
+ $input_errors[] = "The IP address entered is not valid.";
+ }
+
+ 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'];
+ $secretent['ip'] = $_POST['ip'];
+
+ 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><?=gentitle("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); ?>
+ <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" class="vncell">IP address</td>
+ <td width="78%" class="vtable">
+ <input name="ip" type="text" class="formfld" id="ip" size="20" value="<?=htmlspecialchars($pconfig['ip']);?>">
+ <br><span class="vexpl">If you want the user to be assigned a specific IP address, enter it here.</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_secret[$id]): ?>
+ <input name="id" type="hidden" value="<?=$id;?>">
+ <?php endif; ?>
+ </td>
+ </tr>
+ </table>
+</form>
+<?php include("fend.inc"); ?>
+</body>
+</html>
diff --git a/usr/sbin/config_lock.sh b/usr/sbin/config_lock.sh
new file mode 100755
index 0000000..a84d855
--- /dev/null
+++ b/usr/sbin/config_lock.sh
@@ -0,0 +1,9 @@
+#! /usr/local/bin/php -f
+
+
+<?php
+
+require_once("config.inc");
+config_unlock();
+
+?>
diff --git a/usr/sbin/config_unlock.sh b/usr/sbin/config_unlock.sh
new file mode 100755
index 0000000..f534abc
--- /dev/null
+++ b/usr/sbin/config_unlock.sh
@@ -0,0 +1,9 @@
+#! /usr/local/bin/php -f
+
+
+<?php
+
+require_once("config.inc");
+config_lock();
+
+?>
OpenPOWER on IntegriCloud