PFsense 2.3 L2TP, PPTP client problem



  • Sorry for my English.
    I tried create L2TP connection on pfsense 2.3 and have errors

    The following input errors were detected:
    The field Local IP address is required.
    The field Subnet is required.
    The field Remote IP address is required.

    To fix the problem need modify /usr/local/www/interfaces_ppps_edit.php

    Problems caused array indexing _POST['localip' . $j] has numbers
    and  $_POST[$field_label . $iface] interface name

    Here script with changes for L2TP and PPTP. PPPOE and PPP not made because can't check

    /*
    	interfaces_ppps_edit.php
    */
    /* ====================================================================
     *	Copyright (c)  2004-2015  Electric Sheep Fencing, LLC. All rights reserved.
     *	Copyright (c)  2003-2004 Manuel Kasper <mk@neon1.net>
     *	Copyright (c)  2010 Gabriel B. <gnoahb@gmail.com>
     *
     *	Some or all of this file is based on the m0n0wall project which is
     *	Copyright (c)  2004 Manuel Kasper (BSD 2 clause)
     *
     *	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.
     *
     *	3\. All advertising materials mentioning features or use of this software
     *		must display the following acknowledgment:
     *		"This product includes software developed by the pfSense Project
     *		 for use in the pfSense software distribution. (http://www.pfsense.org/).
     *
     *	4\. The names "pfSense" and "pfSense Project" must not be used to
     *		 endorse or promote products derived from this software without
     *		 prior written permission. For written permission, please contact
     *		 coreteam@pfsense.org.
     *
     *	5\. Products derived from this software may not be called "pfSense"
     *		nor may "pfSense" appear in their names without prior written
     *		permission of the Electric Sheep Fencing, LLC.
     *
     *	6\. Redistributions of any form whatsoever must retain the following
     *		acknowledgment:
     *
     *	"This product includes software developed by the pfSense Project
     *	for use in the pfSense software distribution (http://www.pfsense.org/).
     *
     *	THIS SOFTWARE IS PROVIDED BY THE pfSense PROJECT ``AS IS'' AND ANY
     *	EXPRESSED 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 pfSense PROJECT OR
     *	ITS CONTRIBUTORS 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.
     *
     *	====================================================================
     *
     */
    
    ##|+PRIV
    ##|*IDENT=page-interfaces-ppps-edit
    ##|*NAME=Interfaces: PPPs: Edit
    ##|*DESCR=Allow access to the 'Interfaces: PPPs: Edit' page.
    ##|*MATCH=interfaces_ppps_edit.php*
    ##|-PRIV
    
    require("guiconfig.inc");
    require("functions.inc");
    
    define("CRON_MONTHLY_PATTERN", "0 0 1 * *");
    define("CRON_WEEKLY_PATTERN", "0 0 * * 0");
    define("CRON_DAILY_PATTERN", "0 0 * * *");
    define("CRON_HOURLY_PATTERN", "0 * * * *");
    
    if (!is_array($config['ppps']['ppp'])) {
    	$config['ppps']['ppp'] = array();
    }
    
    $a_ppps = &$config['ppps']['ppp'];
    
    $iflist = get_configured_interface_with_descr();
    $portlist = get_interface_list();
    $portlist = array_merge($portlist, $iflist);
    
    if (isset($_REQUEST['type'])) {
    	$pconfig['type'] = $_REQUEST['type'];
    }
    
    if (isset($_REQUEST['id']) && is_numericint($_REQUEST['id'])) {
    	$id = $_REQUEST['id'];
    }
    
    if (isset($_POST['id']) && is_numericint($_POST['id'])) {
    	$id = $_POST['id'];
    }
    
    if (isset($id) && $a_ppps[$id]) {
    	$pconfig['ptpid'] = $a_ppps[$id]['ptpid'];
    	$pconfig['type'] = $a_ppps[$id]['type'];
    	$pconfig['interfaces'] = explode(",", $a_ppps[$id]['ports']);
    	$pconfig['username'] = $a_ppps[$id]['username'];
    	$pconfig['password'] = base64_decode($a_ppps[$id]['password']);
    	if (isset($a_ppps[$id]['ondemand'])) {
    		$pconfig['ondemand'] = true;
    	}
    	$pconfig['idletimeout'] = $a_ppps[$id]['idletimeout'];
    	$pconfig['uptime'] = $a_ppps[$id]['uptime'];
    	$pconfig['descr'] = $a_ppps[$id]['descr'];
    	$bandwidth = explode(",", $a_ppps[$id]['bandwidth']);
    	for ($i = 0; $i < count($bandwidth); $i++)
    		$pconfig['bandwidth'][$pconfig['interfaces'][$i]] = $bandwidth[$i];
    	$mtu = explode(",", $a_ppps[$id]['mtu']);
    	for ($i = 0; $i < count($mtu); $i++)
    		$pconfig['mtu'][$pconfig['interfaces'][$i]] = $mtu[$i];
    	$mru = explode(",", $a_ppps[$id]['mru']);
    	for ($i = 0; $i < count($mru); $i++)
    		$pconfig['mru'][$pconfig['interfaces'][$i]] = $mru[$i];
    	$mrru = explode(",", $a_ppps[$id]['mrru']);
    	for ($i = 0; $i < count($mrru); $i++)
    		$pconfig['mrru'][$pconfig['interfaces'][$i]] = $mrru[$i];
    
    	if (isset($a_ppps[$id]['shortseq'])) {
    		$pconfig['shortseq'] = true;
    	}
    
    	if (isset($a_ppps[$id]['acfcomp'])) {
    		$pconfig['acfcomp'] = true;
    	}
    	if (isset($a_ppps[$id]['protocomp'])) {
    		$pconfig['protocomp'] = true;
    	}
    	if (isset($a_ppps[$id]['vjcomp'])) {
    		$pconfig['vjcomp'] = true;
    	}
    	if (isset($a_ppps[$id]['tcpmssfix'])) {
    		$pconfig['tcpmssfix'] = true;
    	}
    	switch ($a_ppps[$id]['type']) {
    		case "ppp":
    			$pconfig['initstr'] = base64_decode($a_ppps[$id]['initstr']);
    			$pconfig['simpin'] = $a_ppps[$id]['simpin'];
    			$pconfig['pin-wait'] = $a_ppps[$id]['pin-wait'];
    			$pconfig['apn'] = $a_ppps[$id]['apn'];
    			$pconfig['apnum'] = $a_ppps[$id]['apnum'];
    			$pconfig['phone'] = $a_ppps[$id]['phone'];
    			$pconfig['connect-timeout'] = $a_ppps[$id]['connect-timeout'];
    			$pconfig['localip'] = explode(",", $a_ppps[$id]['localip']);
    			$pconfig['gateway'] = explode(",", $a_ppps[$id]['gateway']);
    			break;
    		case "l2tp":
    		case "pptp":
    			$localip = explode(",", $a_ppps[$id]['localip']);
    			$subnet = explode(",", $a_ppps[$id]['subnet']);
    			$gateway = explode(",", $a_ppps[$id]['gateway']);
    			for ($i = 0; $i < count($gateway); $i++)
    			{
    				$pconfig['localip'][$pconfig['interfaces'][$i]] = $localip[$i];
    				$pconfig['subnet'][$pconfig['interfaces'][$i]] = $subnet[$i];
    				$pconfig['gateway'][$pconfig['interfaces'][$i]] = $gateway[$i];
    
    			}
    
    		case "pppoe":
    			$pconfig['provider'] = $a_ppps[$id]['provider'];
    			if (isset($a_ppps[$id]['provider']) and empty($a_ppps[$id]['provider'])) {
    				$pconfig['null_service'] = true;
    			}
    			/* ================================================ */
    			/* = force a connection reset at a specific time? = */
    			/* ================================================ */
    
    			if (isset($a_ppps[$id]['pppoe-reset-type'])) {
    				$pconfig['pppoe-reset-type'] = $a_ppps[$id]['pppoe-reset-type'];
    				$itemhash = getMPDCRONSettings($a_ppps[$id]['if']);
    				$cronitem = $itemhash['ITEM'];
    				if (isset($cronitem)) {
    					$resetTime = "{$cronitem['minute']} {$cronitem['hour']} {$cronitem['mday']} {$cronitem['month']} {$cronitem['wday']}";
    				} else {
    					$resetTime = NULL;
    				}
    
    				if ($a_ppps[$id]['pppoe-reset-type'] == "custom") {
    					$resetTime_a = explode(" ", $resetTime);
    					$pconfig['pppoe_pr_custom'] = true;
    					$pconfig['pppoe_resetminute'] = $resetTime_a[0];
    					$pconfig['pppoe_resethour'] = $resetTime_a[1];
    					/*  just initialize $pconfig['pppoe_resetdate'] if the
    					 *  corresponding item contains appropriate numeric values.
    					 */
    					if ($resetTime_a[2] <> "*" && $resetTime_a[3] <> "*") {
    						$pconfig['pppoe_resetdate'] = "{$resetTime_a[3]}/{$resetTime_a[2]}/" . date("Y");
    					}
    				} else if ($a_ppps[$id]['pppoe-reset-type'] == "preset") {
    					$pconfig['pppoe_pr_preset'] = true;
    
    					switch ($resetTime) {
    						case CRON_MONTHLY_PATTERN:
    							$pconfig['pppoe_monthly'] = true;
    							break;
    						case CRON_WEEKLY_PATTERN:
    							$pconfig['pppoe_weekly'] = true;
    							break;
    						case CRON_DAILY_PATTERN:
    							$pconfig['pppoe_daily'] = true;
    							break;
    						case CRON_HOURLY_PATTERN:
    							$pconfig['pppoe_hourly'] = true;
    							break;
    					}
    				}
    			}
    			break;
    	}
    } else {
    	$pconfig['ptpid'] = interfaces_ptpid_next();
    }
    
    if (isset($_POST) && is_array($_POST) && count($_POST) > 0) {
    	unset($input_errors);
    	$pconfig = $_POST;
    
    	/* okay first of all, cause we are just hiding the PPPoE HTML
    	 * fields related to PPPoE resets, we are going to unset $_POST
    	 * vars, if the reset feature should not be used. Otherwise the
    	 * data validation procedure below, may trigger a false error
    	 * message.
    	 */
    	if (empty($_POST['pppoe-reset-type'])) {
    		unset($_POST['pppoe_resethour']);
    		unset($_POST['pppoe_resetminute']);
    		unset($_POST['pppoe_resetdate']);
    		unset($_POST['pppoe_pr_preset_val']);
    	}
    
    	/* input validation */
    	switch ($_POST['type']) {
    		case "ppp":
    			$reqdfields = explode(" ", "interfaces phone");
    			$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Phone Number"));
    			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
    			break;
    		case "pppoe":
    			if ($_POST['ondemand']) {
    				$reqdfields = explode(" ", "interfaces username passwordfld ondemand idletimeout");
    				$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Username"), gettext("Password"), gettext("Dial on demand"), gettext("Idle timeout value"));
    			} else {
    				$reqdfields = explode(" ", "interfaces username passwordfld");
    				$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Username"), gettext("Password"));
    			}
    			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
    			break;
    		case "l2tp":
    		case "pptp":
    			if ($_POST['ondemand']) {
    				$reqdfields = explode(" ", "interfaces username passwordfld localip subnet gateway ondemand idletimeout");
    				$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Username"), gettext("Password"), gettext("Local IP address"), gettext("Subnet"), gettext("Remote IP address"), gettext("Dial on demand"), gettext("Idle timeout value"));
    			} else {
    				$reqdfields = explode(" ", "interfaces username passwordfld");
    				$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Username"), gettext("Password"));
    			}
    			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
    			break;
    		default:
    			$input_errors[] = gettext("Please choose a Link Type.");
    			break;
    	}
    	if ($_POST['passwordfld'] == $_POST['passwordfld_confirm']) {
    		if ($_POST['passwordfld'] != DMYPWD) {
    			$pconfig['password'] = $_POST['passwordfld'];
    		} else {
    			$pconfig['password'] = base64_decode($a_ppps[$id]['password']);
    		}
    	} else {
    		$input_errors[] = gettext("Password and confirmed password must match.");
    	}
    	if ($_POST['type'] == "ppp" && count($_POST['interfaces']) > 1) {
    		$input_errors[] = gettext("Multilink connections (MLPPP) using the PPP link type is not currently supported. Please select only one Link Interface.");
    	}
    	if ($_POST['provider'] && !is_domain($_POST['provider'])) {
    		$input_errors[] = gettext("The Service name contains invalid characters.");
    	}
    	if ($_POST['provider'] && $_POST['null_service']) {
    		$input_errors[] = gettext("Do not specify both a Service name and a NULL Service name.");
    	}
    	if (($_POST['idletimeout'] != "") && !is_numericint($_POST['idletimeout'])) {
    		$input_errors[] = gettext("The idle timeout value must be an integer.");
    	}
    	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resethour'] <> "" && !is_numericint($_POST['pppoe_resethour']) &&
    	    $_POST['pppoe_resethour'] >= 0 && $_POST['pppoe_resethour'] <=23) {
    		$input_errors[] = gettext("A valid PPPoE reset hour must be specified (0-23).");
    	}
    	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetminute'] <> "" && !is_numericint($_POST['pppoe_resetminute']) &&
    	    $_POST['pppoe_resetminute'] >= 0 && $_POST['pppoe_resetminute'] <=59) {
    		$input_errors[] = gettext("A valid PPPoE reset minute must be specified (0-59).");
    	}
    	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetdate'] <> "" && !is_numeric(str_replace("/", "", $_POST['pppoe_resetdate']))) {
    		$input_errors[] = gettext("A valid PPPoE reset date must be specified (mm/dd/yyyy).");
    	}
    	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetdate'] <> "" && is_numeric(str_replace("/", "", $_POST['pppoe_resetdate']))) {
    		$date_nums = explode("/", $_POST['pppoe_resetdate']);
    		if ($date_nums[0] < 1 || $date_nums[0] > 12) {
    			$input_errors[] = gettext("A valid PPPoE reset month must be specified (1-12) in the Custom PPPoE Periodic reset fields.");
    		}
    		if ($date_nums[1] < 1 || $date_nums[1] > 31) {
    			$input_errors[] = gettext("A valid PPPoE reset day of month must be specified (1-31) in the Custom PPPoE Periodic reset fields. No checks are done on valid # of days per month");
    		}
    		if ($date_nums[2] < date("Y")) {
    			$input_errors[] = gettext("A valid PPPoE reset year must be specified. Don't select a year in the past!");
    		}
    	}
    
    	$port_data = array();
    	if (is_array($_POST['interfaces'])) {
    		foreach ($_POST['interfaces'] as $iface) {
    			if ($_POST['localip'][$iface] && !is_ipaddr($_POST['localip'][$iface])) {
    				$input_errors[] = sprintf(gettext("A valid local IP address must be specified for %s."), $iface);
    			}
    			if ($_POST['gateway'][$iface] && !is_ipaddr($_POST['gateway'][$iface]) && !is_hostname($_POST['gateway'][$iface])) {
    				$input_errors[] = sprintf(gettext("A valid gateway IP address OR hostname must be specified for %s."), $iface);
    			}
    			if ($_POST['bandwidth'][$iface] && !is_numericint($_POST['bandwidth'][$iface])) {
    				$input_errors[] = sprintf(gettext("The bandwidth value for %s must be an integer."), $iface);
    			}
    			if ($_POST['mtu'][$iface] && ($_POST['mtu'][$iface] < 576)) {
    				$input_errors[] = sprintf(gettext("The MTU for %s must be greater than 576 bytes."), $iface);
    			}
    			if ($_POST['mru'][$iface] && ($_POST['mru'][$iface] < 576)) {
    				$input_errors[] = sprintf(gettext("The MRU for %s must be greater than 576 bytes."), $iface);
    			}
    		}
    
    		// Loop through fields associated with an individual link/port and make an array of the data
    		$port_fields = array("localip", "gateway", "subnet", "bandwidth", "mtu", "mru", "mrru");
    		foreach ($_POST['interfaces'] as $iface) {
    			foreach ($port_fields as $field_label) {
    				if (isset($_POST[$field_label . $iface]) &&
    				    strlen($_POST[$field_label . $iface]) > 0) {
    					$port_data[$field_label][$iface] = $_POST[$field_label . $iface];
    					$pconfig[$field_label][$iface] = $_POST[$field_label . $iface];
    					$parent_array = get_parent_interface($iface);
    					$parent = $parent_array[0];
    					$friendly = convert_real_interface_to_friendly_interface_name($parent);
    					if ($field_label == "mtu" && isset($config['interfaces'][$friendly]['mtu']) &&
    					    $_POST[$field_label . $iface] > ($config['interfaces'][$friendly]['mtu'] - 8)) {
    						$input_errors[] = sprintf(gettext("The MTU (%d) is too big for %s (maximum allowed with current settings: %d)."),
    						    $_POST[$field_label . $iface], $iface, $config['interfaces'][$friendly]['mtu'] - 8);
    					}
    				}
    			}
    		}
    	}
    
    	if (!$input_errors) {
    		$ppp = array();
    		if (!isset($id))
    			$ppp['ptpid'] = interfaces_ptpid_next();
    		else
    			$ppp['ptpid'] = $a_ppps[$id]['ptpid'];
    
    		$ppp['type'] = $_POST['type'];
    		$ppp['if'] = $ppp['type'].$ppp['ptpid'];
    		$ppp['ports'] = implode(',', $_POST['interfaces']);
    		$ppp['username'] = $_POST['username'];
    		if ($_POST['passwordfld'] != DMYPWD) {
    			$ppp['password'] = base64_encode($_POST['passwordfld']);
    		} else {
    			$ppp['password'] = $a_ppps[$id]['password'];
    		}
    		$ppp['ondemand'] = $_POST['ondemand'] ? true : false;
    		if (!empty($_POST['idletimeout'])) {
    			$ppp['idletimeout'] = $_POST['idletimeout'];
    		} else {
    			unset($ppp['idletimeout']);
    		}
    		$ppp['uptime'] = $_POST['uptime'] ? true : false;
    		if (!empty($_POST['descr'])) {
    			$ppp['descr'] = $_POST['descr'];
    		} else {
    			unset($ppp['descr']);
    		}
    
    		switch ($_POST['type']) {
    			case "ppp":
    				if (!empty($_POST['initstr'])) {
    					$ppp['initstr'] = base64_encode($_POST['initstr']);
    				} else {
    					unset($ppp['initstr']);
    				}
    				if (!empty($_POST['simpin'])) {
    					$ppp['simpin'] = $_POST['simpin'];
    					$ppp['pin-wait'] = $_POST['pin-wait'];
    				} else {
    					unset($ppp['simpin']);
    					unset($ppp['pin-wait']);
    				}
    
    				if (!empty($_POST['apn'])) {
    					$ppp['apn'] = $_POST['apn'];
    					$ppp['apnum'] = $_POST['apnum'];
    				} else {
    					unset($ppp['apn']);
    					unset($ppp['apnum']);
    				}
    
    				$ppp['phone'] = $_POST['phone'];
    				$ppp['localip'] = implode(',', $port_data['localip']);
    				$ppp['gateway'] = implode(',', $port_data['gateway']);
    				if (!empty($_POST['connect-timeout'])) {
    					$ppp['connect-timeout'] = $_POST['connect-timeout'];
    				} else {
    					unset($ppp['connect-timeout']);
    				}
    				break;
    			case "pppoe":
    				if (!empty($_POST['provider'])) {
    					$ppp['provider'] = $_POST['provider'];
    				} else {
    					unset($ppp['provider']);
    					$ppp['provider'] = $_POST['null_service'] ? true : false;
    				}
    				if (!empty($_POST['pppoe-reset-type'])) {
    					$ppp['pppoe-reset-type'] = $_POST['pppoe-reset-type'];
    				} else {
    					unset($ppp['pppoe-reset-type']);
    				}
    
    				break;
    			case "pptp":
    			case "l2tp":
    				$ppp['localip'] = implode(',', $port_data['localip']);
    				$ppp['subnet'] = implode(',', $port_data['subnet']);
    				$ppp['gateway'] = implode(',', $port_data['gateway']);
    
    				break;
    			default:
    				break;
    
    		}
    
    		$ppp['shortseq'] = $_POST['shortseq'] ? true : false;
    		$ppp['acfcomp'] = $_POST['acfcomp'] ? true : false;
    		$ppp['protocomp'] = $_POST['protocomp'] ? true : false;
    		$ppp['vjcomp'] = $_POST['vjcomp'] ? true : false;
    		$ppp['tcpmssfix'] = $_POST['tcpmssfix'] ? true : false;
    		if (is_array($port_data['bandwidth'])) {
    			$ppp['bandwidth'] = implode(',', $port_data['bandwidth']);
    		}
    		if (is_array($port_data['mtu'])) {
    			$ppp['mtu'] = implode(',', $port_data['mtu']);
    		}
    		if (is_array($port_data['mru'])) {
    			$ppp['mru'] = implode(',', $port_data['mru']);
    		}
    		if (is_array($port_data['mrru'])) {
    			$ppp['mrru'] = implode(',', $port_data['mrru']);
    		}
    
    		/* handle_pppoe_reset is called here because if user changes Link Type from PPPoE to another type we
    		must be able to clear the config data in the <cron> section of config.xml if it exists
    		*/
    		handle_pppoe_reset($_POST);
    
    		if (isset($id) && $a_ppps[$id]) {
    			$a_ppps[$id] = $ppp;
    		} else {
    			$a_ppps[] = $ppp;
    		}
    
    		printf(gettext("DEBUG DATA  %s."), $ppp['mtu']);
    
    		write_config();
    		configure_cron();
    
    		foreach ($iflist as $pppif => $ifdescr) {
    			if ($config['interfaces'][$pppif]['if'] == $ppp['if']) {
    				interface_ppps_configure($pppif);
    			}
    		}
    		header("Location: interfaces_ppps.php");
    		exit;
    	}
    } // end if ($_POST)
    
    $pgtitle = array(gettext("Interfaces"), gettext("PPPs"), gettext("Edit"));
    $shortcut_section = "interfaces";
    include("head.inc");
    
    $types = array("select" => gettext("Select"), "ppp" => gettext("PPP"), "pppoe" => gettext("PPPoE"), "pptp" => gettext("PPTP"), "l2tp" => gettext("L2TP")/*, "tcp" => "TCP", "udp" => "UDP"*/);
    
    $serviceproviders_xml = "/usr/local/share/mobile-broadband-provider-info/serviceproviders.xml";
    $serviceproviders_contents = file_get_contents($serviceproviders_xml);
    $serviceproviders_attr = xml2array($serviceproviders_contents, 1, "attr");
    
    $serviceproviders = &$serviceproviders_attr['serviceproviders']['country'];
    
    //print_r($serviceproviders);
    
    function build_country_list() {
    	global $serviceproviders;
    
    	$list = array();
    
    	// get_country_name is in pfSense-utils.inc
    	$country_list = get_country_name("ALL");
    
    	foreach ($country_list as $country) {
    		$list[$country['code']] = $country['name'];
    	}
    
    	return($list);
    }
    
    function build_link_list() {
    	global $config, $pconfig;
    
    	$linklist = array('list' => array(), 'selected' => array());
    
    	$selected_ports = array();
    
    	if (is_array($pconfig['interfaces'])) {
    		$selected_ports = $pconfig['interfaces'];
    	} elseif (!empty($pconfig['interfaces'])) {
    		$selected_ports = explode(',', $pconfig['interfaces']);
    	}
    
    	if (!is_dir("/var/spool/lock")) {
    		mwexec("/bin/mkdir -p /var/spool/lock");
    	}
    
    	if ($pconfig['type'] == 'ppp') {
    		$serialports = glob("/dev/cua[a-zA-Z][0-9]{,.[0-9],.[0-9][0-9],[0-9],[0-9].[0-9],[0-9].[0-9][0-9]}", GLOB_BRACE);
    		$serport_count = 0;
    
    		foreach ($serialports as $port) {
    			$serport_count++;
    
    			$linklist['list'][$port] = trim($port);
    
    			if (in_array($port, $selected_ports)) {
    				array_push($linklist['selected'], $port);
    			}
    		}
    	} else {
    		$port_count = 0;
    		$portlist = get_interface_list();
    		if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
    			foreach ($config['vlans']['vlan'] as $vlan) {
    				$portlist[$vlan['vlanif']] = $vlan;
    			}
    		}
    		foreach ($portlist as $ifn => $ifinfo) {
    			$port_count++;
    			$string = "";
    
    			if (is_array($ifinfo)) {
    				$string .= $ifn;
    				if ($ifinfo['mac']) {
    					$string .= " ({$ifinfo['mac']})";
    				}
    				if ($ifinfo['friendly']) {
    					$string .= " - {$ifinfo['friendly']}";
    				}
    				if ($ifinfo['descr']) {
    					$string .= " - {$ifinfo['descr']}";
    				}
    			} else {
    				$string .= $ifinfo;
    			}
    
    			$linklist['list'][$ifn] = $string;
    
    			if (in_array($ifn, $selected_ports)) {
    				array_push($linklist['selected'], $ifn);
    			}
    		}
    
    		if ($serport_count > $port_count) {
    			$port_count = $serport_count;
    		}
    	}
    
    	return($linklist);
    }
    
    if ($input_errors) {
    	print_input_errors($input_errors);
    }
    
    $linkparamstr = gettext('Bandwidth is set only for MLPPP connections and when links have different bandwidths' . '
    ' .
    						'MTU defaults to 1492' . '
    ' .
    						'MRU will be auto-negotiated by default' . '
    ' .
    						'Set only for MLPPP connections. MRRU will be auto-negotiated by default.');
    
    $form = new Form();
    
    $section = new Form_Section('PPP Configuration');
    
    $section->addInput(new Form_Select(
    	'type',
    	'Link Type',
    	$pconfig['type'],
    	$types
    ));
    
    $linklist = build_link_list();
    
    $section->addInput(new Form_Select(
    	'interfaces',
    	'Link Interface(s)',
    	$linklist['selected'],
    	$linklist['list'],
    	true // Allow multiples
    ))->addClass('interfaces')->setHelp('Select at least two interfaces for Multilink (MLPPP) connections.');
    
    $section->addInput(new Form_Input(
    	'descr',
    	'Description',
    	'text',
    	$pconfig['descr']
    ))->setHelp('A description may be entered here for administrative reference. Description will appear in the "Interfaces Assign" select lists.');
    
    $section->addInput(new Form_Select(
    	'country',
    	'Country',
    	$pconfig['country'],
    	build_country_list()
    ));
    
    $section->addInput(new Form_Select(
    	'provider',
    	'Provider',
    	$pconfig['provider'],
    	[]
    ));
    
    $section->addInput(new Form_Select(
    	'providerplan',
    	'Plan',
    	$pconfig['providerplan'],
    	[]
    ))->setHelp('Select to fill in service provider data.');
    
    $section->addInput(new Form_Input(
    	'username',
    	'Username',
    	'text',
    	$pconfig['username']
    ));
    
    $section->addPassword(new Form_Input(
    	'passwordfld',
    	'Password',
    	'password',
    	$pconfig['password']
    ));
    
    // These elements are hidden by default, and un-hidden in Javascript
    if ($pconfig['type'] == 'pptp' || $pconfig['type'] == 'l2tp') {
    	$j = 0;
    	foreach ($linklist['list'] as $ifnm => $nm) {
    
    		$group = new Form_Group('IP/Gateway (' . $ifnm . ')');
    
    		$group->add(new Form_IpAddress(
    			'localip' . $ifnm,
    			null,
    			$pconfig['localip'][$ifnm]
    		))->addMask('subnet' . $ifnm, $pconfig['subnet'][$ifnm], 31)->setHelp('IP Address');
    
    		$group->add(new Form_Input(
    			'gateway' . $ifnm,
    			null,
    			'text',
    			$pconfig['gateway'][$ifnm]
    		))->setHelp('IP or Hostname');
    
    		$j++;
    
    		$group->addClass('localip')->addClass('localip' . $ifnm);
    		$section->add($group);
    	}
    }
    
    if ($pconfig['type'] == 'ppp') {
    	$section->addInput(new Form_Input(
    		'phone',
    		'Phone number',
    		'text',
    		$pconfig['phone']
    	))->setHelp('Typically *99# for GSM networks and #777 for CDMA networks');
    }
    
    $section->addInput(new Form_Input(
    	'apn',
    	'Access Point Name (APN)',
    	'text',
    	$pconfig['apn']
    ));
    
    $section->addInput(new Form_Input(
    	'apnum',
    	'APN number (optional)',
    	'text',
    	$pconfig['apnum']
    ))->setHelp('Defaults to 1 if APN is set. Ignored if no APN is set.');
    
    $section->addInput(new Form_Input(
    	'simpin',
    	'SIM PIN',
    	'text',
    	$pconfig['simpin']
    ));
    
    $section->addInput(new Form_Input(
    	'pin-wait',
    	'SIM PIN wait',
    	'text',
    	$pconfig['pin-wait']
    ))->setHelp('Time to wait for SIM to discover network after PIN is sent to SIM (seconds).');
    
    $section->addInput(new Form_Input(
    	'initstr',
    	'Init string',
    	'text',
    	$pconfig['initstr']
    ))->setHelp('Enter the modem initialization string here. Do NOT include the "AT" string at the beginning of the command. ' .
    		  'Many modern USB 3G modems don\'t need an initialization string.');
    
    $section->addInput(new Form_Input(
    	'connect-timeout',
    	'Connection Timeout',
    	'text',
    	$pconfig['connect-timeout']
    ))->setHelp('Enter timeout in seconds for connection to be established (sec.) Default is 45 sec.');
    
    $section->addInput(new Form_Checkbox(
    	'uptime',
    	'Uptime logging',
    	'Enable persistent logging of connection uptime. ',
    	isset($pconfig['uptime'])
    ))->setHelp(sprintf('Causes cumulative uptime to be recorded and displayed on the %sStatus->Interfaces%s page.', '[', '](status_interfaces.php)'));
    
    $group = new Form_Group('Service name');
    $group->addClass('pppoe');
    
    $group->add(new Form_Input(
    	'provider',
    	null,
    	'text',
    	$pconfig['provider']
    ));
    
    $group->add(new Form_Checkbox(
    	'null_service',
    	null,
    	'Configure NULL service name',
    	$pconfig['null_service']
    ));
    
    $group->setHelp('This field can usually be left empty. Service name will not be configured if this field is empty. ' .
    				'Check the "Configure NULL" box to configure a blank Service name.');
    
    $section->add($group);
    
    $section->addInput(new Form_Select(
    	'pppoe-reset-type',
    	'Periodic Reset',
    	$pconfig['pppoe-reset-type'],
    	array(
    		'' => gettext('Disabled'),
    		'custom' => gettext('Custom'),
    		'preset' => gettext('Pre-set')
    	)
    ))->addClass('pppoe')->setHelp('Select a reset timing type');
    
    $group = new Form_Group('Reset Date/Time');
    $group->addClass('pppoe-reset-date');
    
    $group->add(new Form_Input(
    	'pppoe_resethour',
    	null,
    	'text',
    	$pconfig['pppoe_resethour']
    ))->setHelp('Hour');
    
    $group->add(new Form_Input(
    	'pppoe_resetminute',
    	null,
    	'text',
    	$pconfig['pppoe_resetminute']
    ))->setHelp('Minute');
    
    $group->add(new Form_Input(
    	'pppoe_resetdate',
    	null,
    	'text',
    	$pconfig['pppoe_resetdate'],
    	['placeholder' => 'mm/dd/yyyy']
    ))->setHelp('Specific date');
    
    $group->setHelp('Leaving the date field empty will cause the reset to be executed each day at the time specified in the minutes and hour fields. ');
    
    $section->add($group);
    
    $group = new Form_Group('Reset frequency');
    $group->addClass('pppoe-reset-cron');
    
    $group->add(new Form_Checkbox(
    	'pppoe_pr_preset_val',
    	null,
    	'Monthly (0 0 1 * *)',
    	$pconfig['pppoe_monthly'],
    	'monthly'
    ))->displayAsRadio();
    
    $group->add(new Form_Checkbox(
    	'pppoe_pr_preset_val',
    	null,
    	'Weekly (0 0 * * 0)',
    	$pconfig['pppoe_weekly'],
    	'weekly'
    ))->displayAsRadio();
    
    $group->add(new Form_Checkbox(
    	'pppoe_pr_preset_val',
    	null,
    	'Daily (0 0 * * *)',
    	$pconfig['pppoe_daily'],
    	'daily'
    ))->displayAsRadio();
    
    $group->add(new Form_Checkbox(
    	'pppoe_pr_preset_val',
    	null,
    	'Hourly (0 * * * *)',
    	$pconfig['pppoe_hourly'],
    	'hourly'
    ))->displayAsRadio();
    
    $section->add($group);
    
    $btnadv = new Form_Button(
    		'btnadvopts',
    		'Display Advanced',
    		null,
    		'fa-cog'
    );
    
    $btnadv->setAttribute('type','button')->addClass('btn-info btn-sm');
    
    $section->addInput(new Form_StaticText(
    	'Advanced options',
    	$btnadv
    ));
    
    $form->add($section);
    
    $section = new Form_Section('Advanced Configuration');
    $section->addClass('adnlopts');
    
    $section->addInput(new Form_Checkbox(
    	'ondemand',
    	'Dial On Demand',
    	'Enable Dial-on-Demand mode. ',
    	$pconfig['ondemand']
    ))->setHelp('Causes the interface to operate in dial-on-demand mode. Do NOT enable if the link is to remain continuously connected. ' .
    			'The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.');
    
    $section->addInput(new Form_Input(
    	'idletimeout',
    	'Idle Timeout',
    	'text',
    	$pconfig['idletimeout']
    ))->setHelp('If no incoming or outgoing packets are transmitted for the entered number of seconds the connection is brought down.' .
    			'When the idle timeout occurs, if the dial-on-demand option is enabled, mpd goes back into dial-on-demand mode. ' .
    			'Otherwise, the interface is brought down and all associated routes removed.');
    
    $section->addInput(new Form_Checkbox(
    	'vjcomp',
    	'Compression',
    	'Disable vjcomp (compression, auto-negotiated by default).',
    	$pconfig['vjcomp']
    ))->setHelp('Disable vjcomp(compression) (auto-negotiated by default).' . '
    ' .
    				'This option enables Van Jacobson TCP header compression, which saves several bytes per TCP data packet.' .
    				'This option is almost always required. Compression is not effective for TCP connections with enabled modern extensions like time ' .
    				'stamping or SACK, which modify TCP options between sequential packets.');
    
    $section->addInput(new Form_Checkbox(
    	'tcpmssfix',
    	'TCPmssFix',
    	'Disable tcpmssfix (enabled by default).',
    	$pconfig['tcpmssfix']
    ))->setHelp('Causes mpd to adjust incoming and outgoing TCP SYN segments so that the requested maximum segment size is not greater than the amount ' .
    			'allowed by the interface MTU. This is necessary in many setups to avoid problems caused by routers that drop ICMP Datagram Too Big messages. Without these messages, ' .
    			'the originating machine sends data, it passes the rogue router then hits a machine that has an MTU that is not big enough for the data. Because the IP Don\'t Fragment option is set, ' .
    			'this machine sends an ICMP Datagram Too Big message back to the originator and drops the packet. The rogue router drops the ICMP message and the originator never ' .
    			'gets to discover that it must reduce the fragment size or drop the IP Don\'t Fragment option from its outgoing data.');
    
    $section->addInput(new Form_Checkbox(
    	'shortseq',
    	'ShortSeq',
    	'Disable shortseq (auto-negotiated by default).',
    	$pconfig['shortseq']
    ))->setHelp('This option is only meaningful if multi-link PPP is negotiated. It proscribes shorter multi-link fragment headers, saving two bytes on every frame. ' .
    			'It is not necessary to disable this for connections that are not multi-link.');
    
    $section->addInput(new Form_Checkbox(
    	'acfcomp',
    	'ACFComp',
    	'Disable ACF compression (auto-negotiated by default)',
    	$pconfig['acfcomp']
    ))->setHelp('Address and control field compression. This option only applies to asynchronous link types. It saves two bytes per frame.');
    
    $section->addInput(new Form_Checkbox(
    	'protocomp',
    	'ProtoComp',
    	'Disable Protocol compression (auto-negotiated by default)',
    	$pconfig['protocomp']
    ))->setHelp('Protocol field compression. This option saves one byte per frame for most frames.');
    
    // Display the Link parameters. We will hide this by default, then un-hide the selected ones on clicking 'Advanced'
    $j = 0;
    foreach ($linklist['list'] as $ifnm => $nm) {
    
    	$group = new Form_Group('Link Parameters (' . $ifnm . ')');
    
    	$group->add(new Form_Input(
    		'bandwidth' . $ifnm,
    		null,
    		'text',
    		$pconfig['bandwidth'][$ifnm]
    	))->setHelp('Bandwidth');
    
    	$group->add(new Form_Input(
    		'mtu' . $ifnm,
    		null,
    		'text',
    		$pconfig['mtu'][$ifnm]
    	))->setHelp('MTU');
    
    	$group->add(new Form_Input(
    		'mru' . $ifnm,
    		null,
    		'text',
    		$pconfig['mru'][$ifnm]
    	))->setHelp('MRU');
    
    	$group->add(new Form_Input(
    		'mrru' . $ifnm,
    		null,
    		'text',
    		$pconfig['mrru'][$ifnm]
    	))->setHelp('MRRU');
    
    	$j++;
    
    	$section->add($group);
    	$group->addClass('localip sec-advanced')->addClass('linkparam' . $ifnm);
    }
    
    $linkparamhelp = new Form_StaticText(
    	null,
    	'' . $linkparamstr . ''
    );
    
    $section->addInput($linkparamhelp);
    
    $form->add($section);
    
    $form->addGlobal(new Form_Input(
    	'ptpid',
    	null,
    	'hidden',
    	$pconfig['ptpid']
    ));
    
    if (isset($id) && $a_ppps[$id]) {
    	$form->addGlobal(new Form_Input(
    		'id',
    		null,
    		'hidden',
    		$id
    	));
    }
    
    print($form);
    
    ?>
    
    include("foot.inc");
    
    [/i][/i][/i][/i]</cron></gnoahb@gmail.com></mk@neon1.net>
    

Log in to reply