Project

General

Profile

Download (33.4 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/* $Id$ */
3
/*
4
	interfaces_ppps_edit.php
5
	part of m0n0wall (http://m0n0.ch/wall)
6

    
7
	Copyright (C) 2003-2004 Manuel Kasper <mk@neon1.net>.
8
	All rights reserved.
9
	Copyright (C) 2010 Gabriel B. <gnoahb@gmail.com>.
10
	All rights reserved.
11
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
12
	All rights reserved.
13

    
14
	Redistribution and use in source and binary forms, with or without
15
	modification, are permitted provided that the following conditions are met:
16

    
17
	1. Redistributions of source code must retain the above copyright notice,
18
	   this list of conditions and the following disclaimer.
19

    
20
	2. Redistributions in binary form must reproduce the above copyright
21
	   notice, this list of conditions and the following disclaimer in the
22
	   documentation and/or other materials provided with the distribution.
23

    
24
	THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
25
	INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
26
	AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
27
	AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
28
	OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29
	SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30
	INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31
	CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32
	ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33
	POSSIBILITY OF SUCH DAMAGE.
34
*/
35
/*
36
	pfSense_MODULE: interfaces
37
*/
38

    
39
##|+PRIV
40
##|*IDENT=page-interfaces-ppps-edit
41
##|*NAME=Interfaces: PPPs: Edit page
42
##|*DESCR=Allow access to the 'Interfaces: PPPs: Edit' page.
43
##|*MATCH=interfaces_ppps_edit.php*
44
##|-PRIV
45

    
46
require("guiconfig.inc");
47
require("functions.inc");
48

    
49
define("CRON_MONTHLY_PATTERN", "0 0 1 * *");
50
define("CRON_WEEKLY_PATTERN", "0 0 * * 0");
51
define("CRON_DAILY_PATTERN", "0 0 * * *");
52
define("CRON_HOURLY_PATTERN", "0 * * * *");
53

    
54
if (!is_array($config['ppps']['ppp']))
55
	$config['ppps']['ppp'] = array();
56

    
57
$a_ppps = &$config['ppps']['ppp'];
58

    
59
$iflist = get_configured_interface_with_descr();
60
$portlist = get_interface_list();
61
$portlist = array_merge($portlist, $iflist);
62

    
63
if (is_array($config['vlans']['vlan']) && count($config['vlans']['vlan'])) {
64
	foreach ($config['vlans']['vlan'] as $vlan) {
65
		$portlist[$vlan['vlanif']] = $vlan;
66
	}
67
}
68

    
69
if($_GET && $_GET['type'])
70
	$pconfig['type'] = $_GET['type'];
71

    
72
if($_GET && $_GET['country'])
73
	$pconfig['country'] = $_GET['country'];
74

    
75
if($_GET && $_GET['provider'])
76
	$pconfig['provider'] = $_GET['provider'];
77

    
78
if (is_numericint($_GET['id']))
79
	$id = $_GET['id'];
80

    
81
if (isset($_POST['id']) && is_numericint($_POST['id']))
82
	$id = $_POST['id'];
83

    
84
if (isset($id) && $a_ppps[$id]) {
85
	$pconfig['ptpid'] = $a_ppps[$id]['ptpid'];
86
	$pconfig['type'] = $a_ppps[$id]['type'];
87
	//$pconfig['if'] = $a_ppps[$id]['if'];
88
	$pconfig['interfaces'] = $a_ppps[$id]['ports'];
89
	$pconfig['username'] = $a_ppps[$id]['username'];
90
	$pconfig['password'] = base64_decode($a_ppps[$id]['password']);
91
	if (isset($a_ppps[$id]['ondemand']))
92
		$pconfig['ondemand'] = true;
93
	$pconfig['idletimeout'] = $a_ppps[$id]['idletimeout'];
94
	$pconfig['uptime'] = $a_ppps[$id]['uptime'];
95
	$pconfig['descr'] = $a_ppps[$id]['descr'];
96
	$pconfig['bandwidth'] = explode(",",$a_ppps[$id]['bandwidth']);
97
	$pconfig['mtu'] = explode(",",$a_ppps[$id]['mtu']);
98
	$pconfig['mru'] = explode(",",$a_ppps[$id]['mru']);
99
	$pconfig['mrru'] = explode(",",$a_ppps[$id]['mrru']);
100

    
101
	if (isset($a_ppps[$id]['shortseq']))
102
		$pconfig['shortseq'] = true;
103

    
104
	if (isset($a_ppps[$id]['acfcomp']))
105
		$pconfig['acfcomp'] = true;
106

    
107
	if (isset($a_ppps[$id]['protocomp']))
108
		$pconfig['protocomp'] = true;
109

    
110
	if (isset($a_ppps[$id]['vjcomp']))
111
		$pconfig['vjcomp'] = true;
112

    
113
	if (isset($a_ppps[$id]['tcpmssfix']))
114
		$pconfig['tcpmssfix'] = true;
115

    
116
	switch($a_ppps[$id]['type']) {
117
		case "ppp":
118
			$pconfig['initstr'] = base64_decode($a_ppps[$id]['initstr']);
119
			$pconfig['simpin'] = $a_ppps[$id]['simpin'];
120
			$pconfig['pin-wait'] = $a_ppps[$id]['pin-wait'];
121
			$pconfig['apn'] = $a_ppps[$id]['apn'];
122
			$pconfig['apnum'] = $a_ppps[$id]['apnum'];
123
			$pconfig['phone'] = $a_ppps[$id]['phone'];
124
			$pconfig['connect-timeout'] = $a_ppps[$id]['connect-timeout'];
125
			$pconfig['localip'] = explode(",",$a_ppps[$id]['localip']);
126
			$pconfig['gateway'] = explode(",",$a_ppps[$id]['gateway']);
127
			break;
128
		case "l2tp":
129
		case "pptp":
130
			$pconfig['localip'] = explode(",",$a_ppps[$id]['localip']);
131
			$pconfig['subnet'] = explode(",",$a_ppps[$id]['subnet']);
132
			$pconfig['gateway'] = explode(",",$a_ppps[$id]['gateway']);
133
		case "pppoe":
134
			$pconfig['provider'] = $a_ppps[$id]['provider'];
135
			if (isset($a_ppps[$id]['provider']) and empty($a_ppps[$id]['provider']))
136
				$pconfig['null_service'] = true;
137
			/* ================================================ */
138
			/* = force a connection reset at a specific time? = */
139
			/* ================================================ */
140

    
141
			if (isset($a_ppps[$id]['pppoe-reset-type'])) {
142
				$pconfig['pppoe-reset-type'] = $a_ppps[$id]['pppoe-reset-type'];
143
				$itemhash = getMPDCRONSettings($a_ppps[$id]['if']);
144
				$cronitem = $itemhash['ITEM'];
145
				if (isset($cronitem)) {
146
					$resetTime = "{$cronitem['minute']} {$cronitem['hour']} {$cronitem['mday']} {$cronitem['month']} {$cronitem['wday']}";
147
				} else {
148
					$resetTime = NULL;
149
				}
150

    
151
				if ($a_ppps[$id]['pppoe-reset-type'] == "custom") {
152
					$resetTime_a = explode(" ", $resetTime);
153
					$pconfig['pppoe_pr_custom'] = true;
154
					$pconfig['pppoe_resetminute'] = $resetTime_a[0];
155
					$pconfig['pppoe_resethour'] = $resetTime_a[1];
156
					/*	just initialize $pconfig['pppoe_resetdate'] if the
157
					 *	coresponding item contains appropriate numeric values.
158
					 */
159
					if ($resetTime_a[2] != "*" && $resetTime_a[3] != "*")
160
						$pconfig['pppoe_resetdate'] = "{$resetTime_a[3]}/{$resetTime_a[2]}/" . date("Y");
161
				} else if ($a_ppps[$id]['pppoe-reset-type'] == "preset") {
162
					$pconfig['pppoe_pr_preset'] = true;
163

    
164
					switch ($resetTime) {
165
						case CRON_MONTHLY_PATTERN:
166
							$pconfig['pppoe_monthly'] = true;
167
							break;
168
						case CRON_WEEKLY_PATTERN:
169
							$pconfig['pppoe_weekly'] = true;
170
							break;
171
						case CRON_DAILY_PATTERN:
172
							$pconfig['pppoe_daily'] = true;
173
							break;
174
						case CRON_HOURLY_PATTERN:
175
							$pconfig['pppoe_hourly'] = true;
176
							break;
177
					}
178
				}
179
			}
180
			break;
181
	}
182

    
183
} else
184
	$pconfig['ptpid'] = interfaces_ptpid_next();
185

    
186
if ($_POST) {
187

    
188
	unset($input_errors);
189
	$pconfig = $_POST;
190

    
191
	/* okay first of all, cause we are just hiding the PPPoE HTML
192
	 * fields releated to PPPoE resets, we are going to unset $_POST
193
	 * vars, if the reset feature should not be used. Otherwise the
194
	 * data validation procedure below, may trigger a false error
195
	 * message.
196
	 */
197
	if (empty($_POST['pppoe-reset-type'])) {
198
		unset($_POST['pppoe_resethour']);
199
		unset($_POST['pppoe_resetminute']);
200
		unset($_POST['pppoe_resetdate']);
201
		unset($_POST['pppoe_pr_preset_val']);
202
	}
203

    
204
	/* input validation */
205
	switch($_POST['type']) {
206
		case "ppp":
207
			$reqdfields = explode(" ", "interfaces phone");
208
			$reqdfieldsn = array(gettext("Link Interface(s)"),gettext("Phone Number"));
209
			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
210
			break;
211
		case "pppoe":
212
			if ($_POST['ondemand']) {
213
				$reqdfields = explode(" ", "interfaces username passwordfld ondemand idletimeout");
214
				$reqdfieldsn = array(gettext("Link Interface(s)"),gettext("Username"),gettext("Password"),gettext("Dial on demand"),gettext("Idle timeout value"));
215
			} else {
216
				$reqdfields = explode(" ", "interfaces username passwordfld");
217
				$reqdfieldsn = array(gettext("Link Interface(s)"),gettext("Username"),gettext("Password"));
218
			}
219
			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
220
			break;
221
		case "l2tp":
222
		case "pptp":
223
			if ($_POST['ondemand']) {
224
				$reqdfields = explode(" ", "interfaces username passwordfld localip subnet gateway ondemand idletimeout");
225
				$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"));
226
			} else {
227
				$reqdfields = explode(" ", "interfaces username passwordfld localip subnet gateway");
228
				$reqdfieldsn = array(gettext("Link Interface(s)"),gettext("Username"),gettext("Password"),gettext("Local IP address"),gettext("Subnet"),gettext("Remote IP address"));
229
			}
230
			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
231
			break;
232
		default:
233
			$input_errors[] = gettext("Please choose a Link Type.");
234
			break;
235
	}
236
	if ($_POST['type'] == "ppp" && count($_POST['interfaces']) > 1)
237
		$input_errors[] = gettext("Multilink connections (MLPPP) using the PPP link type is not currently supported. Please select only one Link Interface.");
238

    
239
	if ($_POST['provider'] && !is_domain($_POST['provider']))
240
		$input_errors[] = gettext("The Service name contains invalid characters.");
241

    
242
	if ($_POST['provider'] && $_POST['null_service'])
243
		$input_errors[] = gettext("Do not specify both a Service name and a NULL Service name.");
244

    
245
	if (($_POST['idletimeout'] != "") && !is_numericint($_POST['idletimeout']))
246
		$input_errors[] = gettext("The idle timeout value must be an integer.");
247

    
248
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resethour'] != "" && !is_numericint($_POST['pppoe_resethour']) &&
249
		$_POST['pppoe_resethour'] >= 0 && $_POST['pppoe_resethour'] <=23)
250
		$input_errors[] = gettext("A valid PPPoE reset hour must be specified (0-23).");
251

    
252
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetminute'] != "" && !is_numericint($_POST['pppoe_resetminute']) &&
253
		$_POST['pppoe_resetminute'] >= 0 && $_POST['pppoe_resetminute'] <=59)
254
		$input_errors[] = gettext("A valid PPPoE reset minute must be specified (0-59).");
255

    
256
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetdate'] != "" && !is_numeric(str_replace("/", "", $_POST['pppoe_resetdate'])))
257
		$input_errors[] = gettext("A valid PPPoE reset date must be specified (mm/dd/yyyy).");
258

    
259
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetdate'] != "" && is_numeric(str_replace("/", "", $_POST['pppoe_resetdate']))) {
260
		$date_nums = explode("/",$_POST['pppoe_resetdate']);
261
		if ($date_nums[0] < 1 || $date_nums[0] > 12)
262
			$input_errors[] = gettext("A valid PPPoE reset month must be specified (1-12) in the Custom PPPoE Periodic reset fields.");
263

    
264
		if ($date_nums[1] < 1 || $date_nums[1] > 31)
265
			$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");
266

    
267
		if ($date_nums[2] < date("Y"))
268
			$input_errors[] = gettext("A valid PPPoE reset year must be specified. Don't select a year in the past!");
269
	}
270

    
271
	foreach($_POST['interfaces'] as $iface){
272
		if ($_POST['localip'][$iface] && !is_ipaddr($_POST['localip'][$iface]))
273
			$input_errors[] = sprintf(gettext("A valid local IP address must be specified for %s."),$iface);
274

    
275
		if ($_POST['gateway'][$iface] && !is_ipaddr($_POST['gateway'][$iface]) && !is_hostname($_POST['gateway'][$iface]))
276
			$input_errors[] = sprintf(gettext("A valid gateway IP address OR hostname must be specified for %s."),$iface);
277

    
278
		if ($_POST['bandwidth'][$iface] && !is_numericint($_POST['bandwidth'][$iface]))
279
			$input_errors[] = sprintf(gettext("The bandwidth value for %s must be an integer."),$iface);
280

    
281
		if ($_POST['mtu'][$iface] && ($_POST['mtu'][$iface] < 576))
282
			$input_errors[] = sprintf(gettext("The MTU for %s must be greater than 576 bytes."),$iface);
283

    
284
		if ($_POST['mru'][$iface] && ($_POST['mru'][$iface] < 576))
285
			$input_errors[] = sprintf(gettext("The MRU for %s must be greater than 576 bytes."),$iface);
286
	}
287

    
288
/*
289
	foreach ($a_ppps as $ppp) {
290
		if (isset($id) && ($a_ppps[$id]) && ($a_ppps[$id] === $ppp))
291
			continue;
292

    
293
		if ($ppp['serialport'] == $_POST['serialport']) {
294
			$input_errors[] = "Serial port is in use";
295
			break;
296
		}
297
	}
298
*/
299

    
300
	if (!$input_errors) {
301
		$ppp = array();
302
		$ppp['ptpid'] = $_POST['ptpid'];
303
		$ppp['type'] = $_POST['type'];
304
		$ppp['if'] = $ppp['type'].$ppp['ptpid'];
305
		$ppp['ports'] = implode(',',$_POST['interfaces']);
306
		$ppp['username'] = $_POST['username'];
307
		$ppp['password'] = base64_encode($_POST['passwordfld']);
308
		$ppp['ondemand'] = $_POST['ondemand'] ? true : false;
309

    
310
		if (!empty($_POST['idletimeout']))
311
			$ppp['idletimeout'] = $_POST['idletimeout'];
312
		else
313
			unset($ppp['idletimeout']);
314

    
315
		$ppp['uptime'] = $_POST['uptime'] ? true : false;
316

    
317
		if (!empty($_POST['descr']))
318
			$ppp['descr'] = $_POST['descr'];
319
		else
320
			unset($ppp['descr']);
321

    
322
		// Loop through fields associated with a individual link/port and make an array of the data
323
		$port_fields = array("localip", "gateway", "subnet", "bandwidth", "mtu", "mru", "mrru");
324

    
325
		foreach($_POST['interfaces'] as $iface){
326
			foreach($port_fields as $field_label){
327
				if (isset($_POST[$field_label][$iface]))
328
					$port_data[$field_label][] = $_POST[$field_label][$iface];
329
			}
330
		}
331

    
332
		switch($_POST['type']) {
333
			case "ppp":
334
				if (!empty($_POST['initstr']))
335
					$ppp['initstr'] = base64_encode($_POST['initstr']);
336
				else
337
					unset($ppp['initstr']);
338

    
339
				if (!empty($_POST['simpin'])) {
340
					$ppp['simpin'] = $_POST['simpin'];
341
					$ppp['pin-wait'] = $_POST['pin-wait'];
342
				} else {
343
					unset($ppp['simpin']);
344
					unset($ppp['pin-wait']);
345
				}
346

    
347
				if (!empty($_POST['apn'])){
348
					$ppp['apn'] = $_POST['apn'];
349
					$ppp['apnum'] = $_POST['apnum'];
350
				} else {
351
					unset($ppp['apn']);
352
					unset($ppp['apnum']);
353
				}
354

    
355
				$ppp['phone'] = $_POST['phone'];
356
				$ppp['localip'] = implode(',',$port_data['localip']);
357
				$ppp['gateway'] = implode(',',$port_data['gateway']);
358

    
359
				if (!empty($_POST['connect-timeout']))
360
					$ppp['connect-timeout'] = $_POST['connect-timeout'];
361
				else
362
					unset($ppp['connect-timeout']);
363
				break;
364
			case "pppoe":
365
				if (!empty($_POST['provider']))
366
					$ppp['provider'] = $_POST['provider'];
367
				else{
368
					unset($ppp['provider']);
369
					$ppp['provider'] = $_POST['null_service'] ? true : false;
370
				}
371

    
372
				if (!empty($_POST['pppoe-reset-type']))
373
					$ppp['pppoe-reset-type'] = $_POST['pppoe-reset-type'];
374
				else
375
					unset($ppp['pppoe-reset-type']);
376

    
377
				break;
378
			case "pptp":
379
			case "l2tp":
380
				$ppp['localip'] = implode(',',$port_data['localip']);
381
				$ppp['subnet'] = implode(',',$port_data['subnet']);
382
				$ppp['gateway'] = implode(',',$port_data['gateway']);
383
				break;
384
			default:
385
				break;
386

    
387
		}
388

    
389
		$ppp['shortseq'] = $_POST['shortseq'] ? true : false;
390
		$ppp['acfcomp'] = $_POST['acfcomp'] ? true : false;
391
		$ppp['protocomp'] = $_POST['protocomp'] ? true : false;
392
		$ppp['vjcomp'] = $_POST['vjcomp'] ? true : false;
393
		$ppp['tcpmssfix'] = $_POST['tcpmssfix'] ? true : false;
394
		$ppp['bandwidth'] = implode(',', $port_data['bandwidth']);
395

    
396
		if (is_array($port_data['mtu']))
397
			$ppp['mtu'] = implode(',', $port_data['mtu']);
398

    
399
		if (is_array($port_data['mru']))
400
			$ppp['mru'] = implode(',', $port_data['mru']);
401

    
402
		if (is_array($port_data['mrru']))
403
			$ppp['mrru'] = implode(',', $port_data['mrru']);
404

    
405
		/* handle_pppoe_reset is called here because if user changes Link Type from PPPoE to another type we
406
		must be able to clear the config data in the <cron> section of config.xml if it exists
407
		*/
408
		handle_pppoe_reset($_POST);
409

    
410
		if (isset($id) && $a_ppps[$id])
411
			$a_ppps[$id] = $ppp;
412
		else
413
			$a_ppps[] = $ppp;
414

    
415
		write_config();
416
		configure_cron();
417

    
418
		foreach ($iflist as $pppif => $ifdescr) {
419
			if ($config['interfaces'][$pppif]['if'] == $ppp['if'])
420
				interface_ppps_configure($pppif);
421
		}
422
		header("Location: interfaces_ppps.php");
423
		exit;
424
	}
425
} // end if($_POST)
426

    
427
$closehead = false;
428
$pgtitle = array(gettext("Interfaces"),gettext("PPPs"),gettext("Edit"));
429
$shortcut_section = "interfaces";
430
include("head.inc");
431

    
432
$types = array("select" => gettext("Select"), "ppp" => "PPP", "pppoe" => "PPPoE", "pptp" => "PPTP",	 "l2tp" => "L2TP"/*, "tcp" => "TCP", "udp" => "UDP"*/  );
433

    
434
$serviceproviders_xml = "/usr/local/share/mobile-broadband-provider-info/serviceproviders.xml";
435
$serviceproviders_contents = file_get_contents($serviceproviders_xml);
436
$serviceproviders_attr = xml2array($serviceproviders_contents,1,"attr");
437

    
438
$serviceproviders = &$serviceproviders_attr['serviceproviders']['country'];
439

    
440
function build_country_list() {
441
	global $serviceproviders;
442

    
443
	$list = array();
444

    
445
	// get_country_name is in pfSense-utils.inc
446
	$country_list = get_country_name("ALL");
447

    
448
	foreach($country_list as $country) {
449
		$list[$country['code']] = $country['name'];
450
	}
451

    
452
	return($list);
453
}
454

    
455
function build_provider_list($country) {
456
	global $serviceproviders;
457

    
458
	$list = array();
459

    
460
	foreach($serviceproviders as $sp) {
461
		if($sp['attr']['code'] == strtolower($country)) {
462
			if(is_array($sp['provider'][0])) {
463
				foreach($sp['provider'] as $provider) {
464
					array_push($list, $provider['name']['value']);
465
				 }
466
			}
467
		}
468
	}
469

    
470
	return array_combine($list, $list);
471
}
472

    
473
function build_plans_list($country, $provider) {
474
	global $serviceproviders;
475

    
476
	$list = array();
477

    
478
	foreach($serviceproviders as $sprecord) {
479
		if($sprecord['attr']['code'] == strtolower($country)) {
480
			foreach($sprecord['provider'] as $sp) {
481
				if(strtolower($sp['name']['value']) == strtolower($provider)) {
482
					if(array_key_exists('gsm', $sp)) {
483

    
484
						if(array_key_exists('attr',$sp['gsm']['apn'])) {
485
							$name = ($sp['gsm']['apn']['name'] ? $sp['gsm']['apn']['name'] : $sp['name']['value']);
486
							echo $name . ":" . $sp['gsm']['apn']['attr']['value'];
487
						} else {
488
							foreach($sp['gsm']['apn'] as $apn_info) {
489
								$name = ($apn_info['name']['value'] ? $apn_info['name']['value'] : $apn_info['gsm']['apn']['name']);
490

    
491
								$key = $apn_info['attr']['value'];
492
								$list[$key] = $name . ($key ? ' ':'') . '- ' . $key;
493
							}
494
						}
495
					}
496

    
497
					if(array_key_exists('cdma',$sp)) {
498
						$name = $sp['cdma']['name']['value'] ? $sp['cdma']['name']['value']:$sp['name']['value'];
499
						$key = 'CDMA';
500
						$list[$key] = $name . ' - ' . $key;
501
					}
502
				}
503
			}
504
		}
505
	}
506

    
507
	return($list);
508
}
509

    
510
$port_count = 0;
511
$serport_count = 0;
512

    
513
function build_link_list() {
514
	global $pconfig, $portlist, $port_count, $serport_count;
515

    
516
	$linklist = array('list'	 => array(),
517
					  'selected' => array());
518

    
519
	$selected_ports = explode(',',$pconfig['interfaces']);
520

    
521
	if (!is_dir("/var/spool/lock"))
522
		mwexec("/bin/mkdir -p /var/spool/lock");
523

    
524
	if($pconfig['type'] == 'ppp') {
525
		$serialports = glob("/dev/cua?[0-9]{,.[0-9]}", GLOB_BRACE);
526
		//DEBUG
527
		$serialports = glob("/dev/tty?[0-9]{,.[0-9]}", GLOB_BRACE);
528

    
529
		$serport_count = 0;
530

    
531
		foreach ($serialports as $port) {
532
			$serport_count++;
533

    
534
			$linklist['list'][$port] = trim($port);
535

    
536
			if (in_array($port, $selected_ports))
537
				array_push($linklist['selected'], $port);
538
		}
539
	}
540
	else {
541
		$port_count = 0;
542
		foreach ($portlist as $ifn => $ifinfo){
543
			$port_count++;
544
			$string = "";
545

    
546
			if (is_array($ifinfo)) {
547
				$string .= $ifn;
548
				if ($ifinfo['mac'])
549
				$string .= " ({$ifinfo['mac']})";
550
			} else
551
				$string .= $ifinfo;
552

    
553
			$linklist['list'][$ifn] = $string;
554

    
555
			if (in_array($ifn, $selected_ports))
556
				array_push($linklist['selected'], $ifn);
557
		}
558

    
559
		if($serport_count > $port_count)
560
			$port_count=$serport_count;
561
	}
562

    
563
	return($linklist);
564
}
565

    
566
if ($input_errors)
567
	print_input_errors($input_errors);
568

    
569
$linkparamstr = gettext('Bandwidth is set only for MLLP conncetions and when links have diferent bandwidths' . '<br />' .
570
						'MTU defaults to 1492' . '<br />' .
571
						'MRU will be auto-negotiated by default' . '<br />' .
572
						'Set only for MLLP conncetions. MRRU will be auto-negotiated by default.');
573

    
574
require('classes/Form.class.php');
575

    
576
$form = new Form();
577

    
578
$section = new Form_Section('PPPs Configuration');
579

    
580
$section->addInput(new Form_Select(
581
	'type',
582
	'Link Type',
583
	$pconfig['type'],
584
	$types
585
));
586

    
587
$linklist = build_link_list();
588

    
589
$section->addInput(new Form_Select(
590
	'interfaces',
591
	'Link Interface(s)',
592
	$linklist['selected'],
593
	$linklist['list'],
594
	true // Allow multiples
595
))->addClass('interfaces')->setHelp('Select at least two interfaces for Multilink (MLPPP) connections.');
596

    
597
$section->addInput(new Form_Input(
598
	'descr',
599
	'Description',
600
	'text',
601
	$pconfig['descr']
602
))->setHelp('You may enter a description here for your reference. Description will appear in the "Interfaces Assign" select lists.');
603

    
604
$section->addInput(new Form_Select(
605
	'country',
606
	'Country',
607
	$pconfig['country'],
608
	build_country_list()
609
));
610

    
611
$section->addInput(new Form_Select(
612
	'provider',
613
	'Provider',
614
	$pconfig['provider'],
615
	build_provider_list($pconfig['country'])
616
));
617

    
618
$section->addInput(new Form_Select(
619
	'providerplan',
620
	'Plan',
621
	$pconfig['providerplan'],
622
	build_plans_list($pconfig['country'], $pconfig['provider'])
623
))->setHelp('Select to fill in data for your service provider.');
624

    
625
$section->addInput(new Form_Input(
626
	'username',
627
	'Username',
628
	'text',
629
	$pconfig['username']
630
));
631

    
632
$section->addInput(new Form_Input(
633
	'passwordfld',
634
	'Password',
635
	'password',
636
	$pconfig['descr']
637
));
638

    
639
// These elements arehidden by default, and un-hidden in Javascript
640
if($pconfig['type'] == 'pptp' || $pconfig['type'] == 'l2tp') {
641
	$j = 0;
642
	foreach($linklist['list'] as $ifnm =>$nm) {
643

    
644
		$group = new Form_Group('IP/Gateway (' . $ifnm . ')');
645

    
646
		$group->add(new Form_IpAddress(
647
			'localiplabel' . $j,
648
			null,
649
			$pconfig['localip'][$j]
650
		))->addMask('subnet' . $j, $pconfig['subnet'][$j], 31)->setHelp('IP Address');
651

    
652
		$group->add(new Form_Input(
653
			'gateway' . $j,
654
			null,
655
			'password',
656
			$pconfig['gateway'][$j]
657
		))->setHelp('IP or Hostname');
658

    
659
		$j++;
660

    
661
		$group->addClass('localip')->addClass('localip' . $ifnm);
662
		$section->add($group);
663
	}
664
}
665

    
666
if($pconfig['type'] == 'ppp') {
667
	$section->addInput(new Form_Input(
668
		'phone',
669
		'Phone number',
670
		'text',
671
		$pconfig['phone']
672
	))->setHelp('Typically *99# for GSM networks and #777 for CDMA networks');
673
}
674

    
675
$section->addInput(new Form_Input(
676
	'apn',
677
	'Access Point Name (APN)',
678
	'text',
679
	$pconfig['apn']
680
));
681

    
682
$section->addInput(new Form_Input(
683
	'apnum',
684
	'APN number (optional)',
685
	'text',
686
	$pconfig['apnum']
687
))->setHelp('Defaults to 1 if APN is set. Ignored if no APN is set.');
688

    
689
$section->addInput(new Form_Input(
690
	'simpin',
691
	'SIM PIN',
692
	'text',
693
	$pconfig['simpin']
694
));
695

    
696
$section->addInput(new Form_Input(
697
	'pin-wait',
698
	'SIM PIN wait',
699
	'text',
700
	$pconfig['pin-wait']
701
))->setHelp('Time to wait for SIM to discover network after PIN is sent to SIM (seconds).');
702

    
703
$section->addInput(new Form_Input(
704
	'initstr',
705
	'Init string',
706
	'text',
707
	$pconfig['initstr']
708
))->setHelp('Enter the modem initialization string here. Do NOT include the "AT" string at the beginning of the command. ' .
709
		  'Many modern USB 3G modems don\'t need an initialization string.');
710

    
711
$section->addInput(new Form_Input(
712
	'connect-timeout',
713
	'Connection Timeout',
714
	'text',
715
	$pconfig['connect-timeout']
716
))->setHelp('Enter timeout in seconds for connection to be established (sec.) Default is 45 sec.');
717

    
718
$section->addInput(new Form_Checkbox(
719
	'uptime',
720
	'Uptime logging',
721
	'Enable persistent logging of connection uptime. ',
722
	$pconfig['uptime']
723
))->setHelp(sprintf('Causes cumulative uptime to be recorded and displayed on the %sStatus->Interfaces%s page.', '<a href="status_interfaces.php">', '</a>'));
724

    
725
$group = new Form_Group('Service name');
726
$group->addClass('pppoe');
727

    
728
$group->add(new Form_Input(
729
	'provider',
730
	null,
731
	'text',
732
	$pconfig['provider']
733
));
734

    
735
$group->add(new Form_Checkbox(
736
	'null_service',
737
	null,
738
	'Configure NULL service name',
739
	$pconfig['null_service']
740
));
741

    
742
$group->setHelp('This field can usually be left empty. Service name will not be configured if this field is empty. ' .
743
				'Check the "Configure NULL" box to configure a blank Service name.');
744

    
745
$section->add($group);
746

    
747
$section->addInput(new Form_Select(
748
	'pppoe-reset-type',
749
	'Periodic Reset',
750
	$pconfig['pppoe-reset-type'],
751
	array(
752
		'' => 'Disabled',
753
		'custom' => 'Custom',
754
		'preset' => 'Pre-set'
755
	)
756
))->addClass('pppoe')->setHelp('Select a reset timing type');
757

    
758
$group = new Form_Group('Rest Date/Time');
759
$group->addClass('pppoe-reset-date');
760

    
761
$group->add(new Form_Input(
762
	'pppoe_resethour',
763
	null,
764
	'text',
765
	$pconfig['pppoe_resethour']
766
))->setHelp('Hour');
767

    
768
$group->add(new Form_Input(
769
	'pppoe_resetminute',
770
	null,
771
	'text',
772
	$pconfig['pppoe_resetminute']
773
))->setHelp('Minute');
774

    
775
$group->add(new Form_Input(
776
	'pppoe_resetdate',
777
	null,
778
	'text',
779
	$pconfig['pppoe_resetdate'],
780
	['placeholder' => 'mm/dd/yyyy']
781
))->setHelp('Specific date');
782

    
783
$group->setHelp('Leaving the date field empty will cause the reset to be executed each day at the time you specified in the minutes and hour fields. ');
784

    
785
$section->add($group);
786

    
787
$group = new Form_Group('Rest frequency');
788
$group->addClass('pppoe-reset-cron');
789

    
790
$group->add(new Form_Checkbox(
791
	'pppoe_pr_preset_val',
792
	null,
793
	'Monthly (0 0 1 * *)',
794
	$pconfig['pppoe_monthly'],
795
	'monthly'
796
))->displayAsRadio();
797

    
798
$group->add(new Form_Checkbox(
799
	'pppoe_pr_preset_val',
800
	null,
801
	'Weekly (0 0 * * 0)',
802
	$pconfig['pppoe_weekly'],
803
	'weekly'
804
))->displayAsRadio();
805

    
806
$group->add(new Form_Checkbox(
807
	'pppoe_pr_preset_val',
808
	null,
809
	'Daily (0 0 * * *)',
810
	$pconfig['pppoe_daily'],
811
	'daily'
812
))->displayAsRadio();
813

    
814
$group->add(new Form_Checkbox(
815
	'pppoe_pr_preset_val',
816
	null,
817
	'Hourly (0 * * * *)',
818
	$pconfig['pppoe_hourly'],
819
	'hourly'
820
))->displayAsRadio();
821

    
822
$section->add($group);
823

    
824
$btnadvanced = new Form_Button(
825
		'btnadvanced',
826
		'Show'
827
);
828

    
829
$btnadvanced->removeClass('btn-primary')->addClass('btn-default btn-sm');
830

    
831
$section->addInput(new Form_StaticText(
832
	'Advanced options',
833
	$btnadvanced
834
));
835

    
836
$form->add($section);
837

    
838
$section = new Form_Section('Advanced Configuration');
839
$section->addClass('sec-advanced'); // This will allow the section to be hidden/shown by calling e.g.: hideClass('advanced', true);
840

    
841
$section->addInput(new Form_Checkbox(
842
	'ondemand',
843
	'Dial On Demand',
844
	'Enable Dial-on-Demand mode. ',
845
	$pconfig['ondemand']
846
))->setHelp('Causes the interface to operate in dial-on-demand mode. Do NOT enable if you want your link to be always up. ' .
847
			'The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.');
848

    
849
$section->addInput(new Form_Input(
850
	'idletimeout',
851
	'Idle Timeout',
852
	'text',
853
	$pconfig['idletimeout']
854
))->setHelp('If no incoming or outgoing packets are transmitted for the entered number of seconds the connection is brought down.' .
855
			'When the idle timeout occurs, if the dial-on-demand option is enabled, mpd goes back into dial-on-demand mode. ' .
856
			'Otherwise, the interface is brought down and all associated routes removed.');
857

    
858
$section->addInput(new Form_Checkbox(
859
	'vjcomp',
860
	'Compression',
861
	'Disable vjcomp (compression, auto-negotiated by default).',
862
	$pconfig['vjcomp']
863
))->setHelp('Disable vjcomp(compression) (auto-negotiated by default).' . '<br />' .
864
				'This option enables Van Jacobson TCP header compression, which saves several bytes per TCP data packet.' .
865
				'This option is almost always required. Compression is not effective for TCP connections with enabled modern extensions like time ' .
866
				'stamping or SACK, which modify TCP options between sequential packets.');
867

    
868
$section->addInput(new Form_Checkbox(
869
	'tcpmssfix',
870
	'TCPmssFix',
871
	'Disable tcpmssfix (enabled by default).',
872
	$pconfig['tcpmssfix']
873
))->setHelp('Causes mpd to adjust incoming and outgoing TCP SYN segments so that the requested maximum segment size is not greater than the amount ' .
874
			'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, ' .
875
			'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, ' .
876
			'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 ' .
877
			'gets to discover that it must reduce the fragment size or drop the IP Don\'t Fragment option from its outgoing data.');
878

    
879
$section->addInput(new Form_Checkbox(
880
	'shortseq',
881
	'ShortSeq',
882
	'Disable shortseq (auto-negotiated by default).',
883
	$pconfig['shortseq']
884
))->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. ' .
885
			'It is not necessary to disable this for connections that are not multi-link.');
886

    
887
$section->addInput(new Form_Checkbox(
888
	'acfcomp',
889
	'ACFComp',
890
	'Disable ACF compression (auto-negotiated by default)',
891
	$pconfig['acfcomp']
892
))->setHelp('Address and control field compression. This option only applies to asynchronous link types. It saves two bytes per frame.');
893

    
894
$section->addInput(new Form_Checkbox(
895
	'protocomp',
896
	'ProtoComp',
897
	'Disable Protocol compression (auto-negotiated by default)',
898
	$pconfig['protocomp']
899
))->setHelp('Protocol field compression. This option saves one byte per frame for most frames.');
900

    
901
// Display the Link parameters. We will hide this by default, then un-hide the selected ones on clicking 'Advanced'
902
$j = 0;
903

    
904
foreach($linklist['list'] as $ifnm =>$nm) {
905

    
906
	$group = new Form_Group('Link Parameters (' . $ifnm . ')');
907

    
908
	$group->add(new Form_Input(
909
		'bandwidth' . $j,
910
		null,
911
		'text',
912
		$pconfig['bandwidth'][$j]
913
	))->setHelp('Bandwidth');
914

    
915
	$group->add(new Form_Input(
916
		'mtu' . $j,
917
		null,
918
		'password',
919
		$pconfig['mtu'][$j]
920
	))->setHelp('MTU');
921

    
922
	$group->add(new Form_Input(
923
		'mru' . $j,
924
		null,
925
		'password',
926
		$pconfig['mru'][$j]
927
	))->setHelp('MRU');
928

    
929
	$group->add(new Form_Input(
930
		'mrru' . $j,
931
		null,
932
		'password',
933
		$pconfig['mrru'][$j]
934
	))->setHelp('MRRU');
935

    
936
	$j++;
937

    
938
	$section->add($group);
939

    
940
	$group->addClass('localip sec-advanced')->addClass('linkparam' . $ifnm);
941
}
942

    
943
$linkparamhelp = new Form_StaticText(
944
	null,
945
	'<span id="linkparamhelp">' . $linkparamstr . '</span>'
946
);
947

    
948
$section->addInput($linkparamhelp);
949

    
950
if (isset($id) && $a_ppps[$id]) {
951
	$section->addInput(new Form_Input(
952
		'id',
953
		null,
954
		'hidden',
955
		$id
956
	));
957
}
958

    
959
$section->addInput(new Form_Input(
960
	'ptpid',
961
	null,
962
	'hidden',
963
	$ptpid
964
));
965

    
966
$form->add($section);
967

    
968
print($form);
969

    
970
?>
971

    
972
<script>
973
//<![CDATA[
974
events.push(function(){
975
	var showadvanced = false;
976

    
977
	// Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden
978
	function hideInput(id, hide) {
979
		if(hide)
980
			$('#' + id).parent().parent('div').addClass('hidden');
981
		else
982
			$('#' + id).parent().parent('div').removeClass('hidden');
983
	}
984

    
985
	// Hides the <div> in which the specified checkbox lives so that the checkbox, its label and help text are hidden
986
	function hideCheckbox(id, hide) {
987
		if(hide)
988
			$('#' + id).parent().parent().parent('div').addClass('hidden');
989
		else
990
			$('#' + id).parent().parent().parent('div').removeClass('hidden');
991
	}
992

    
993
	// Disables the specified input element
994
	function disableInput(id, disable) {
995
		$('#' + id).prop("disabled", disable);
996
	}
997

    
998
	// Hides all elements of the specified class. This will usually be a section or group
999
	function hideClass(s_class, hide) {
1000
		if(hide)
1001
			$('.' + s_class).hide();
1002
		else
1003
			$('.' + s_class).show();
1004
	}
1005

    
1006
	// Simple test in which clicking the ‘clear’ button toggles certain display elements
1007
	function setAdvVisible() {
1008
		// Update the button text and toggle showadvanced
1009
		if(showadvanced) {
1010
			$("#btnadvanced").prop('value', 'Hide');
1011
			showadvanced = false;
1012
		}
1013
		else {
1014
			$("#btnadvanced").prop('value', 'Show');
1015
			showadvanced = true;
1016
		}
1017

    
1018
		hideClass('sec-advanced', showadvanced);
1019

    
1020
		// The options that follow are only shown if type == 'ppp'
1021
		var ppptype = ($('#type').val() == 'ppp');
1022

    
1023
		hideInput('apnum', showadvanced && ppptype);
1024
		hideInput('simpin', showadvanced && ppptype);
1025
		hideInput('pin-wait', showadvanced && ppptype);
1026
		hideInput('initstr', showadvanced && ppptype);
1027
		hideInput('connect-timeout', showadvanced && ppptype);
1028
		hideCheckbox('uptime', showadvanced && ppptype);
1029

    
1030
		// The options that follow are only shown if type == 'pppoe'
1031
		var pppoetype = ($('#type').val() != 'pppoe');
1032

    
1033
		hideClass('pppoe', showadvanced || pppoetype);
1034
		hideInput('pppoe-reset-type', showadvanced || pppoetype);
1035

    
1036
		hideResetDisplay(true);
1037

    
1038
		hideInterfaces();
1039
	}
1040

    
1041
	function hideResetDisplay(hide) {
1042

    
1043
		hideClass('pppoe-reset-date', true);
1044
		hideClass('pppoe-reset-cron', true);
1045

    
1046
		if(!hide) {
1047
			switch($('#pppoe-reset-type').val()) {
1048
				case 'custom' :
1049
					hideClass('pppoe-reset-date', false);
1050
					break;
1051
				case 'preset' :
1052
					hideClass('pppoe-reset-cron', false);
1053
					break;
1054
			}
1055
		}
1056
	}
1057

    
1058
	function hideInterfaces() {
1059
		hideClass('localip', true);
1060
		hideClass('linkparam', true);
1061
		hideInput('linkparamhelp', true);
1062

    
1063
		var selected = $('.interfaces').val();
1064
		var length = selected.length;
1065

    
1066
		for(var i=0; i<length; i++) {
1067
			hideClass('localip' + selected[i], false);
1068

    
1069
			if(!showadvanced) {
1070
				hideClass('linkparam' + selected[i], false);
1071
				hideInput('linkparamhelp', false);
1072
			   }
1073
		}
1074
	}
1075

    
1076
	// Make the ‘btnadvanced’ button a plain button, not a submit button
1077
	$("#btnadvanced").prop('type','button');
1078

    
1079
	$("#btnadvanced").click(function() {
1080
		setAdvVisible();
1081
	});
1082

    
1083
	$('#pppoe-reset-type').on('change', function() {
1084
		hideResetDisplay(false);
1085
	});
1086

    
1087
	// When interfaces changed, read the selected items and unhide the corresponding IP/Gateway controls
1088
	// Multiselect boxes must be handled by class
1089
	$('.interfaces').on('change', function() {
1090
		hideInterfaces();
1091
	 });
1092

    
1093
	// When type, country or provider are changed, reload the page and build the new selector arrays
1094
	$('#type').on('change', function() {
1095
		window.location = 'interfaces_ppps_edit.php?id=' + $('#id').val() + '&type=' + this.value;
1096
	});
1097

    
1098
	$('#country').on('change', function() {
1099
		window.location = 'interfaces_ppps_edit.php?id=' + $('#id').val() + '&country=' + this.value + '&type=' + $('#type').val();
1100
	});
1101

    
1102
	$('#provider').on('change', function() {
1103
		window.location = 'interfaces_ppps_edit.php?id=' + $('#id').val() + '&provider=' + this.value + '&type=' + $('#type').val() + '&country=' + $('#country').val();
1104
	});
1105

    
1106
	// Set element visibility on initial page load
1107
	setAdvVisible();
1108

    
1109
	hideClass('linkparam', true);
1110
});
1111
//]]>
1112

    
1113
</script>
1114
<?php
1115

    
1116
include("foot.inc");
(95-95/237)