diff options
-rw-r--r-- | etc/inc/interfaces.inc | 2 | ||||
-rw-r--r-- | etc/inc/regdomain.inc | 162 | ||||
-rwxr-xr-x | usr/local/www/interfaces.php | 61 |
3 files changed, 223 insertions, 2 deletions
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index 4cca084..c66fad2 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -1426,7 +1426,7 @@ function interface_wireless_clone($realif, $wlcfg) { function interface_sync_wireless_clones(&$ifcfg, $sync_changes = false) { global $config, $g; - $shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel', 'distance'); + $shared_settings = array('standard', 'turbo', 'protmode', 'txpower', 'channel', 'distance', 'regdomain', 'regcountry', 'reglocation'); if(!is_interface_wireless($ifcfg['if'])) return; diff --git a/etc/inc/regdomain.inc b/etc/inc/regdomain.inc new file mode 100644 index 0000000..a8f1a7f --- /dev/null +++ b/etc/inc/regdomain.inc @@ -0,0 +1,162 @@ +<?php +/* $Id$ */ +/* + regdomain.inc + functions to parse /etc/regdomain.xml + + Copyright (C) 2010 Erik Fonnesbeck + + based on xmlparse.inc + Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>. + + 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. +*/ + +/* The following items will be treated as arrays in regdomain.xml */ +function listtags_rd() { + $ret = explode(" ", + "band country flags freqband netband rd " + ); + return $ret; +} + +function startElement_rd($parser, $name, $attrs) { + global $parsedcfg, $depth, $curpath, $havedata, $listtags; + + array_push($curpath, strtolower($name)); + + $ptr =& $parsedcfg; + 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)); + + if (!empty($attrs)) + $ptr[count($ptr)]['attributes'] = $attrs; + + } 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))); + } else if (!empty($attrs)) { + $ptr['attributes'] = $attrs; + } + + $depth++; + $havedata = $depth; +} + +function endElement_rd($parser, $name) { + global $depth, $curpath, $parsedcfg, $havedata, $listtags; + + if ($havedata == $depth) { + $ptr =& $parsedcfg; + foreach ($curpath as $path) { + $ptr =& $ptr[$path]; + } + if (!isset($ptr)) + $ptr = ""; + } + + array_pop($curpath); + + if (in_array(strtolower($name), $listtags)) + array_pop($curpath); + + $depth--; +} + +function cData_rd($parser, $data) { + global $depth, $curpath, $parsedcfg, $havedata; + + $data = trim($data, "\t\n\r"); + + if ($data != "") { + $ptr =& $parsedcfg; + foreach ($curpath as $path) { + $ptr =& $ptr[$path]; + } + + if (is_string($ptr)) { + $ptr .= $data; + } else { + if (trim($data, " ") != "") { + $ptr = $data; + $havedata++; + } + } + } +} + +function parse_xml_regdomain($rdfile = '/etc/regdomain.xml', $rootobj = 'regulatory-data') { + global $listtags; + $listtags = listtags_rd(); + return parse_xml_regdomain_raw($rdfile, $rootobj); +} + +function parse_xml_regdomain_raw($rdfile, $rootobj) { + + global $depth, $curpath, $parsedcfg, $havedata, $listtags; + $parsedcfg = array(); + $curpath = array(); + $depth = 0; + $havedata = 0; + + $xml_parser = xml_parser_create(); + + xml_set_element_handler($xml_parser, "startElement_rd", "endElement_rd"); + xml_set_character_data_handler($xml_parser, "cData_rd"); + xml_parser_set_option($xml_parser,XML_OPTION_SKIP_WHITE, 1); + + if (!($fp = fopen($rdfile, "r"))) { + die("Error: could not open XML input\n"); + } + + while ($data = fread($fp, 4096)) { + if (!xml_parse($xml_parser, $data, feof($fp))) { + log_error(sprintf("XML error: %s at line %d\n", + xml_error_string(xml_get_error_code($xml_parser)), + xml_get_current_line_number($xml_parser))); + return -1; + } + } + xml_parser_free($xml_parser); + + if (!$parsedcfg[$rootobj]) { + die("XML error: no $rootobj object found!\n"); + } + + return $parsedcfg[$rootobj]; +} + +?> diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php index 3aa715a..e091d0e 100755 --- a/usr/local/www/interfaces.php +++ b/usr/local/www/interfaces.php @@ -52,6 +52,7 @@ require("filter.inc"); require("shaper.inc"); require("rrd.inc"); require("vpn.inc"); +require('regdomain.inc'); if ($_REQUEST['if']) { $if = $_REQUEST['if']; @@ -218,6 +219,7 @@ if (isset($wancfg['wireless'])) { interface_wireless_clone($wlanif, $wancfg); $wlanbaseif = interface_get_wireless_base($wancfg['if']); $wl_modes = get_wireless_modes($if); + $wl_regdomains = parse_xml_regdomain(); $pconfig['standard'] = $wancfg['wireless']['standard']; $pconfig['mode'] = $wancfg['wireless']['mode']; $pconfig['protmode'] = $wancfg['wireless']['protmode']; @@ -225,6 +227,9 @@ if (isset($wancfg['wireless'])) { $pconfig['channel'] = $wancfg['wireless']['channel']; $pconfig['txpower'] = $wancfg['wireless']['txpower']; $pconfig['distance'] = $wancfg['wireless']['distance']; + $pconfig['regdomain'] = $wancfg['wireless']['regdomain']; + $pconfig['regcountry'] = $wancfg['wireless']['regcountry']; + $pconfig['reglocation'] = $wancfg['wireless']['reglocation']; $pconfig['wme_enable'] = isset($wancfg['wireless']['wme']['enable']); if (isset($wancfg['wireless']['puren']['enable'])) $pconfig['puremode'] = '11n'; @@ -694,7 +699,7 @@ function handle_pppoe_reset() { } function handle_wireless_post() { - global $_POST, $config, $g, $wancfg, $if; + global $_POST, $config, $g, $wancfg, $if, $wl_regdomains; if (!is_array($wancfg['wireless'])) $wancfg['wireless'] = array(); $wancfg['wireless']['standard'] = $_POST['standard']; @@ -705,6 +710,17 @@ function handle_wireless_post() { $wancfg['wireless']['authmode'] = $_POST['authmode']; $wancfg['wireless']['txpower'] = $_POST['txpower']; $wancfg['wireless']['distance'] = $_POST['distance']; + $wancfg['wireless']['regdomain'] = $_POST['regdomain']; + $wancfg['wireless']['regcountry'] = $_POST['regcountry']; + $wancfg['wireless']['reglocation'] = $_POST['reglocation']; + if (!empty($wancfg['wireless']['regdomain']) && !empty($wancfg['wireless']['regcountry'])) { + foreach($wl_regdomains['country-codes']['country'] as $wl_country) { + if ($wancfg['wireless']['regcountry'] == $wl_country['attributes']['ID']) { + $wancfg['wireless']['regdomain'] = $wl_country['rd'][0]['attributes']['REF']; + break; + } + } + } if (!is_array($wancfg['wireless']['wpa'])) $wancfg['wireless']['wpa'] = array(); $wancfg['wireless']['wpa']['macaddr_acl'] = $_POST['macaddr_acl']; @@ -1366,6 +1382,49 @@ $types = array("none" => "None", "static" => "Static", "dhcp" => "DHCP", "pppoe" </td> </tr> <tr> + <td valign="top" class="vncell">Regulatory settings</td> + <td class="vtable"> + Regulatory domain<br/> + <select name="regdomain" class="formselect" id="regdomain"> + <option <? if (empty($pconfig['regdomain'])) echo "selected"; ?> value="">Default</option> + <?php + foreach($wl_regdomains['regulatory-domains']['rd'] as $wl_regdomain) { + echo "<option "; + if ($pconfig['regdomain'] == $wl_regdomain['attributes']['ID']) { + echo "selected "; + } + echo "value=\"{$wl_regdomain['attributes']['ID']}\">{$wl_regdomain['name']}</option>\n"; + } + ?> + </select> + <br/><br/> + Country (listed with country code and regulatory domain)<br/> + <select name="regcountry" class="formselect" id="regcountry"> + <option <? if (empty($pconfig['regcountry'])) echo "selected"; ?> value="">Default</option> + <?php + foreach($wl_regdomains['country-codes']['country'] as $wl_country) { + echo "<option "; + if ($pconfig['regcountry'] == $wl_country['attributes']['ID']) { + echo "selected "; + } + echo "value=\"{$wl_country['attributes']['ID']}\">{$wl_country['name']} -- ({$wl_country['attributes']['ID']}, " . strtoupper($wl_country['rd'][0]['attributes']['REF']) . ")</option>\n"; + } + ?> + </select> + <br/> + Note: Any country setting other than "Default" will override the regulatory domain setting. + <br/><br/> + Location<br/> + <select name="reglocation" class="formselect" id="reglocation"> + <option <? if ($pconfig['reglocation'] == 'indoor') echo "selected"; ?> value="indoor">Indoor</option> + <option <? if ($pconfig['reglocation'] == 'outdoor') echo "selected"; ?> value="outdoor">Outdoor</option> + <option <? if ($pconfig['reglocation'] == 'anywhere') echo "selected"; ?> value="anywhere">Anywhere</option> + </select> + <br/><br/> + These settings may affect which channels are available and the maximum transmit power allowed on those channels. Using the correct settings to comply with local regulatory requirements is recommended. + </td> + </tr> + <tr> <td colspan="2" valign="top" height="16"></td> </tr> <tr> |