Project

General

Profile

Download (33.7 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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    
187
} else {
188
	$pconfig['ptpid'] = interfaces_ptpid_next();
189
}
190

    
191
if ($_POST) {
192

    
193
	unset($input_errors);
194
	$pconfig = $_POST;
195

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

    
209
	/* input validation */
210
	switch ($_POST['type']) {
211
		case "ppp":
212
			$reqdfields = explode(" ", "interfaces phone");
213
			$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Phone Number"));
214
			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
215
			break;
216
		case "pppoe":
217
			if ($_POST['ondemand']) {
218
				$reqdfields = explode(" ", "interfaces username passwordfld ondemand idletimeout");
219
				$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Username"), gettext("Password"), gettext("Dial on demand"), gettext("Idle timeout value"));
220
			} else {
221
				$reqdfields = explode(" ", "interfaces username passwordfld");
222
				$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Username"), gettext("Password"));
223
			}
224
			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
225
			break;
226
		case "l2tp":
227
		case "pptp":
228
			if ($_POST['ondemand']) {
229
				$reqdfields = explode(" ", "interfaces username passwordfld localip subnet gateway ondemand idletimeout");
230
				$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"));
231
			} else {
232
				$reqdfields = explode(" ", "interfaces username passwordfld localip subnet gateway");
233
				$reqdfieldsn = array(gettext("Link Interface(s)"), gettext("Username"), gettext("Password"), gettext("Local IP address"), gettext("Subnet"), gettext("Remote IP address"));
234
			}
235
			do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
236
			break;
237
		default:
238
			$input_errors[] = gettext("Please choose a Link Type.");
239
			break;
240
	}
241
	if ($_POST['type'] == "ppp" && count($_POST['interfaces']) > 1) {
242
		$input_errors[] = gettext("Multilink connections (MLPPP) using the PPP link type is not currently supported. Please select only one Link Interface.");
243
	}
244
	if ($_POST['provider'] && !is_domain($_POST['provider'])) {
245
		$input_errors[] = gettext("The Service name contains invalid characters.");
246
	}
247
	if ($_POST['provider'] && $_POST['null_service']) {
248
		$input_errors[] = gettext("Do not specify both a Service name and a NULL Service name.");
249
	}
250
	if (($_POST['idletimeout'] != "") && !is_numericint($_POST['idletimeout'])) {
251
		$input_errors[] = gettext("The idle timeout value must be an integer.");
252
	}
253
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resethour'] <> "" && !is_numericint($_POST['pppoe_resethour']) &&
254
	    $_POST['pppoe_resethour'] >= 0 && $_POST['pppoe_resethour'] <=23) {
255
		$input_errors[] = gettext("A valid PPPoE reset hour must be specified (0-23).");
256
	}
257
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetminute'] <> "" && !is_numericint($_POST['pppoe_resetminute']) &&
258
	    $_POST['pppoe_resetminute'] >= 0 && $_POST['pppoe_resetminute'] <=59) {
259
		$input_errors[] = gettext("A valid PPPoE reset minute must be specified (0-59).");
260
	}
261
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetdate'] <> "" && !is_numeric(str_replace("/", "", $_POST['pppoe_resetdate']))) {
262
		$input_errors[] = gettext("A valid PPPoE reset date must be specified (mm/dd/yyyy).");
263
	}
264
	if ($_POST['pppoe-reset-type'] == "custom" && $_POST['pppoe_resetdate'] <> "" && is_numeric(str_replace("/", "", $_POST['pppoe_resetdate']))) {
265
		$date_nums = explode("/", $_POST['pppoe_resetdate']);
266
		if ($date_nums[0] < 1 || $date_nums[0] > 12) {
267
			$input_errors[] = gettext("A valid PPPoE reset month must be specified (1-12) in the Custom PPPoE Periodic reset fields.");
268
		}
269
		if ($date_nums[1] < 1 || $date_nums[1] > 31) {
270
			$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");
271
		}
272
		if ($date_nums[2] < date("Y")) {
273
			$input_errors[] = gettext("A valid PPPoE reset year must be specified. Don't select a year in the past!");
274
		}
275
	}
276

    
277
	if (is_array($_POST['interfaces'])) {
278
		foreach ($_POST['interfaces'] as $iface) {
279
			if ($_POST['localip'][$iface] && !is_ipaddr($_POST['localip'][$iface])) {
280
				$input_errors[] = sprintf(gettext("A valid local IP address must be specified for %s."), $iface);
281
			}
282
			if ($_POST['gateway'][$iface] && !is_ipaddr($_POST['gateway'][$iface]) && !is_hostname($_POST['gateway'][$iface])) {
283
				$input_errors[] = sprintf(gettext("A valid gateway IP address OR hostname must be specified for %s."), $iface);
284
			}
285
			if ($_POST['bandwidth'][$iface] && !is_numericint($_POST['bandwidth'][$iface])) {
286
				$input_errors[] = sprintf(gettext("The bandwidth value for %s must be an integer."), $iface);
287
			}
288
			if ($_POST['mtu'][$iface] && ($_POST['mtu'][$iface] < 576)) {
289
				$input_errors[] = sprintf(gettext("The MTU for %s must be greater than 576 bytes."), $iface);
290
			}
291
			if ($_POST['mru'][$iface] && ($_POST['mru'][$iface] < 576)) {
292
				$input_errors[] = sprintf(gettext("The MRU for %s must be greater than 576 bytes."), $iface);
293
			}
294
		}
295
	}
296

    
297
/*
298
	foreach ($a_ppps as $ppp) {
299
		if (isset($id) && ($a_ppps[$id]) && ($a_ppps[$id] === $ppp)) {
300
			continue;
301
		}
302

    
303
		if ($ppp['serialport'] == $_POST['serialport']) {
304
			$input_errors[] = "Serial port is in use";
305
			break;
306
		}
307
	}
308
*/
309

    
310
	if (!$input_errors) {
311
		$ppp = array();
312
		$ppp['ptpid'] = $_POST['ptpid'];
313
		$ppp['type'] = $_POST['type'];
314
		$ppp['if'] = $ppp['type'].$ppp['ptpid'];
315
		$ppp['ports'] = implode(',', $_POST['interfaces']);
316
		$ppp['username'] = $_POST['username'];
317
		$ppp['password'] = base64_encode($_POST['passwordfld']);
318
		$ppp['ondemand'] = $_POST['ondemand'] ? true : false;
319
		if (!empty($_POST['idletimeout'])) {
320
			$ppp['idletimeout'] = $_POST['idletimeout'];
321
		} else {
322
			unset($ppp['idletimeout']);
323
		}
324
		$ppp['uptime'] = $_POST['uptime'] ? true : false;
325
		if (!empty($_POST['descr'])) {
326
			$ppp['descr'] = $_POST['descr'];
327
		} else {
328
			unset($ppp['descr']);
329
		}
330

    
331
		// Loop through fields associated with an individual link/port and make an array of the data
332
		$port_fields = array("localip", "gateway", "subnet", "bandwidth", "mtu", "mru", "mrru");
333
		foreach ($_POST['interfaces'] as $iface) {
334
			foreach ($port_fields as $field_label) {
335
				if (isset($_POST[$field_label][$iface])) {
336
					$port_data[$field_label][] = $_POST[$field_label][$iface];
337
				}
338
			}
339
		}
340

    
341
		switch ($_POST['type']) {
342
			case "ppp":
343
				if (!empty($_POST['initstr'])) {
344
					$ppp['initstr'] = base64_encode($_POST['initstr']);
345
				} else {
346
					unset($ppp['initstr']);
347
				}
348
				if (!empty($_POST['simpin'])) {
349
					$ppp['simpin'] = $_POST['simpin'];
350
					$ppp['pin-wait'] = $_POST['pin-wait'];
351
				} else {
352
					unset($ppp['simpin']);
353
					unset($ppp['pin-wait']);
354
				}
355

    
356
				if (!empty($_POST['apn'])) {
357
					$ppp['apn'] = $_POST['apn'];
358
					$ppp['apnum'] = $_POST['apnum'];
359
				} else {
360
					unset($ppp['apn']);
361
					unset($ppp['apnum']);
362
				}
363

    
364
				$ppp['phone'] = $_POST['phone'];
365
				$ppp['localip'] = implode(',', $port_data['localip']);
366
				$ppp['gateway'] = implode(',', $port_data['gateway']);
367
				if (!empty($_POST['connect-timeout'])) {
368
					$ppp['connect-timeout'] = $_POST['connect-timeout'];
369
				} else {
370
					unset($ppp['connect-timeout']);
371
				}
372
				break;
373
			case "pppoe":
374
				if (!empty($_POST['provider'])) {
375
					$ppp['provider'] = $_POST['provider'];
376
				} else {
377
					unset($ppp['provider']);
378
					$ppp['provider'] = $_POST['null_service'] ? true : false;
379
				}
380
				if (!empty($_POST['pppoe-reset-type'])) {
381
					$ppp['pppoe-reset-type'] = $_POST['pppoe-reset-type'];
382
				} else {
383
					unset($ppp['pppoe-reset-type']);
384
				}
385

    
386
				break;
387
			case "pptp":
388
			case "l2tp":
389
				$ppp['localip'] = implode(',', $port_data['localip']);
390
				$ppp['subnet'] = implode(',', $port_data['subnet']);
391
				$ppp['gateway'] = implode(',', $port_data['gateway']);
392
				break;
393
			default:
394
				break;
395

    
396
		}
397

    
398
		$ppp['shortseq'] = $_POST['shortseq'] ? true : false;
399
		$ppp['acfcomp'] = $_POST['acfcomp'] ? true : false;
400
		$ppp['protocomp'] = $_POST['protocomp'] ? true : false;
401
		$ppp['vjcomp'] = $_POST['vjcomp'] ? true : false;
402
		$ppp['tcpmssfix'] = $_POST['tcpmssfix'] ? true : false;
403
		$ppp['bandwidth'] = implode(',', $port_data['bandwidth']);
404
		if (is_array($port_data['mtu'])) {
405
			$ppp['mtu'] = implode(',', $port_data['mtu']);
406
		}
407
		if (is_array($port_data['mru'])) {
408
			$ppp['mru'] = implode(',', $port_data['mru']);
409
		}
410
		if (is_array($port_data['mrru'])) {
411
			$ppp['mrru'] = implode(',', $port_data['mrru']);
412
		}
413

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

    
419
		if (isset($id) && $a_ppps[$id]) {
420
			$a_ppps[$id] = $ppp;
421
		} else {
422
			$a_ppps[] = $ppp;
423
		}
424

    
425
		write_config();
426
		configure_cron();
427

    
428
		foreach ($iflist as $pppif => $ifdescr) {
429
			if ($config['interfaces'][$pppif]['if'] == $ppp['if']) {
430
				interface_ppps_configure($pppif);
431
			}
432
		}
433
		header("Location: interfaces_ppps.php");
434
		exit;
435
	}
436
} // end if ($_POST)
437

    
438
$closehead = false;
439
$pgtitle = array(gettext("Interfaces"), gettext("PPPs"), gettext("Edit"));
440
$shortcut_section = "interfaces";
441
include("head.inc");
442

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

    
445
$serviceproviders_xml = "/usr/local/share/mobile-broadband-provider-info/serviceproviders.xml";
446
$serviceproviders_contents = file_get_contents($serviceproviders_xml);
447
$serviceproviders_attr = xml2array($serviceproviders_contents,1,"attr");
448

    
449
$serviceproviders = &$serviceproviders_attr['serviceproviders']['country'];
450

    
451
function build_country_list() {
452
	global $serviceproviders;
453

    
454
	$list = array();
455

    
456
	// get_country_name is in pfSense-utils.inc
457
	$country_list = get_country_name("ALL");
458

    
459
	foreach($country_list as $country) {
460
		$list[$country['code']] = $country['name'];
461
	}
462

    
463
	return($list);
464
}
465

    
466
function build_provider_list($country) {
467
	global $serviceproviders;
468

    
469
	$list = array();
470

    
471
	foreach($serviceproviders as $sp) {
472
		if($sp['attr']['code'] == strtolower($country)) {
473
			if(is_array($sp['provider'][0])) {
474
				foreach($sp['provider'] as $provider) {
475
					array_push($list, $provider['name']['value']);
476
				 }
477
			}
478
		}
479
	}
480

    
481
	return array_combine($list, $list);
482
}
483

    
484
function build_plans_list($country, $provider) {
485
	global $serviceproviders;
486

    
487
	$list = array();
488

    
489
	foreach($serviceproviders as $sprecord) {
490
		if($sprecord['attr']['code'] == strtolower($country)) {
491
			foreach($sprecord['provider'] as $sp) {
492
				if(strtolower($sp['name']['value']) == strtolower($provider)) {
493
					if(array_key_exists('gsm', $sp)) {
494

    
495
						if(array_key_exists('attr',$sp['gsm']['apn'])) {
496
							$name = ($sp['gsm']['apn']['name'] ? $sp['gsm']['apn']['name'] : $sp['name']['value']);
497
							echo $name . ":" . $sp['gsm']['apn']['attr']['value'];
498
						} else {
499
							foreach($sp['gsm']['apn'] as $apn_info) {
500
								$name = ($apn_info['name']['value'] ? $apn_info['name']['value'] : $apn_info['gsm']['apn']['name']);
501

    
502
								$key = $apn_info['attr']['value'];
503
								$list[$key] = $name . ($key ? ' ':'') . '- ' . $key;
504
							}
505
						}
506
					}
507

    
508
					if(array_key_exists('cdma',$sp)) {
509
						$name = $sp['cdma']['name']['value'] ? $sp['cdma']['name']['value']:$sp['name']['value'];
510
						$key = 'CDMA';
511
						$list[$key] = $name . ' - ' . $key;
512
					}
513
				}
514
			}
515
		}
516
	}
517

    
518
	return($list);
519
}
520

    
521
$port_count = 0;
522
$serport_count = 0;
523

    
524
function build_link_list() {
525
	global $pconfig, $portlist, $port_count, $serport_count;
526

    
527
	$linklist = array('list'	 => array(),
528
					  'selected' => array());
529

    
530
	$selected_ports = explode(',',$pconfig['interfaces']);
531

    
532
	if (!is_dir("/var/spool/lock"))
533
		mwexec("/bin/mkdir -p /var/spool/lock");
534

    
535
	if($pconfig['type'] == 'ppp') {
536
		$serialports = glob("/dev/cua?[0-9]{,.[0-9]}", GLOB_BRACE);
537
		//DEBUG
538
		$serialports = glob("/dev/tty?[0-9]{,.[0-9]}", GLOB_BRACE);
539

    
540
		$serport_count = 0;
541

    
542
		foreach ($serialports as $port) {
543
			$serport_count++;
544

    
545
			$linklist['list'][$port] = trim($port);
546

    
547
			if (in_array($port, $selected_ports))
548
				array_push($linklist['selected'], $port);
549
		}
550
	}
551
	else {
552
		$port_count = 0;
553
		foreach ($portlist as $ifn => $ifinfo){
554
			$port_count++;
555
			$string = "";
556

    
557
			if (is_array($ifinfo)) {
558
				$string .= $ifn;
559
				if ($ifinfo['mac'])
560
				$string .= " ({$ifinfo['mac']})";
561
			} else
562
				$string .= $ifinfo;
563

    
564
			$linklist['list'][$ifn] = $string;
565

    
566
			if (in_array($ifn, $selected_ports))
567
				array_push($linklist['selected'], $ifn);
568
		}
569

    
570
		if($serport_count > $port_count)
571
			$port_count=$serport_count;
572
	}
573

    
574
	return($linklist);
575
}
576

    
577
if ($input_errors)
578
	print_input_errors($input_errors);
579

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

    
585
require('classes/Form.class.php');
586

    
587
$form = new Form();
588

    
589
$section = new Form_Section('PPPs Configuration');
590

    
591
$section->addInput(new Form_Select(
592
	'type',
593
	'Link Type',
594
	$pconfig['type'],
595
	$types
596
));
597

    
598
$linklist = build_link_list();
599

    
600
$section->addInput(new Form_Select(
601
	'interfaces',
602
	'Link Interface(s)',
603
	$linklist['selected'],
604
	$linklist['list'],
605
	true // Allow multiples
606
))->addClass('interfaces')->setHelp('Select at least two interfaces for Multilink (MLPPP) connections.');
607

    
608
$section->addInput(new Form_Input(
609
	'descr',
610
	'Description',
611
	'text',
612
	$pconfig['descr']
613
))->setHelp('You may enter a description here for your reference. Description will appear in the "Interfaces Assign" select lists.');
614

    
615
$section->addInput(new Form_Select(
616
	'country',
617
	'Country',
618
	$pconfig['country'],
619
	build_country_list()
620
));
621

    
622
$section->addInput(new Form_Select(
623
	'provider',
624
	'Provider',
625
	$pconfig['provider'],
626
	build_provider_list($pconfig['country'])
627
));
628

    
629
$section->addInput(new Form_Select(
630
	'providerplan',
631
	'Plan',
632
	$pconfig['providerplan'],
633
	build_plans_list($pconfig['country'], $pconfig['provider'])
634
))->setHelp('Select to fill in data for your service provider.');
635

    
636
$section->addInput(new Form_Input(
637
	'username',
638
	'Username',
639
	'text',
640
	$pconfig['username']
641
));
642

    
643
$section->addInput(new Form_Input(
644
	'passwordfld',
645
	'Password',
646
	'password',
647
	$pconfig['descr']
648
));
649

    
650
// These elements arehidden by default, and un-hidden in Javascript
651
if($pconfig['type'] == 'pptp' || $pconfig['type'] == 'l2tp') {
652
	$j = 0;
653
	foreach($linklist['list'] as $ifnm =>$nm) {
654

    
655
		$group = new Form_Group('IP/Gateway (' . $ifnm . ')');
656

    
657
		$group->add(new Form_IpAddress(
658
			'localiplabel' . $j,
659
			null,
660
			$pconfig['localip'][$j]
661
		))->addMask('subnet' . $j, $pconfig['subnet'][$j], 31)->setHelp('IP Address');
662

    
663
		$group->add(new Form_Input(
664
			'gateway' . $j,
665
			null,
666
			'password',
667
			$pconfig['gateway'][$j]
668
		))->setHelp('IP or Hostname');
669

    
670
		$j++;
671

    
672
		$group->addClass('localip')->addClass('localip' . $ifnm);
673
		$section->add($group);
674
	}
675
}
676

    
677
if($pconfig['type'] == 'ppp') {
678
	$section->addInput(new Form_Input(
679
		'phone',
680
		'Phone number',
681
		'text',
682
		$pconfig['phone']
683
	))->setHelp('Typically *99# for GSM networks and #777 for CDMA networks');
684
}
685

    
686
$section->addInput(new Form_Input(
687
	'apn',
688
	'Access Point Name (APN)',
689
	'text',
690
	$pconfig['apn']
691
));
692

    
693
$section->addInput(new Form_Input(
694
	'apnum',
695
	'APN number (optional)',
696
	'text',
697
	$pconfig['apnum']
698
))->setHelp('Defaults to 1 if APN is set. Ignored if no APN is set.');
699

    
700
$section->addInput(new Form_Input(
701
	'simpin',
702
	'SIM PIN',
703
	'text',
704
	$pconfig['simpin']
705
));
706

    
707
$section->addInput(new Form_Input(
708
	'pin-wait',
709
	'SIM PIN wait',
710
	'text',
711
	$pconfig['pin-wait']
712
))->setHelp('Time to wait for SIM to discover network after PIN is sent to SIM (seconds).');
713

    
714
$section->addInput(new Form_Input(
715
	'initstr',
716
	'Init string',
717
	'text',
718
	$pconfig['initstr']
719
))->setHelp('Enter the modem initialization string here. Do NOT include the "AT" string at the beginning of the command. ' .
720
		  'Many modern USB 3G modems don\'t need an initialization string.');
721

    
722
$section->addInput(new Form_Input(
723
	'connect-timeout',
724
	'Connection Timeout',
725
	'text',
726
	$pconfig['connect-timeout']
727
))->setHelp('Enter timeout in seconds for connection to be established (sec.) Default is 45 sec.');
728

    
729
$section->addInput(new Form_Checkbox(
730
	'uptime',
731
	'Uptime logging',
732
	'Enable persistent logging of connection uptime. ',
733
	$pconfig['uptime']
734
))->setHelp(sprintf('Causes cumulative uptime to be recorded and displayed on the %sStatus->Interfaces%s page.', '<a href="status_interfaces.php">', '</a>'));
735

    
736
$group = new Form_Group('Service name');
737
$group->addClass('pppoe');
738

    
739
$group->add(new Form_Input(
740
	'provider',
741
	null,
742
	'text',
743
	$pconfig['provider']
744
));
745

    
746
$group->add(new Form_Checkbox(
747
	'null_service',
748
	null,
749
	'Configure NULL service name',
750
	$pconfig['null_service']
751
));
752

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

    
756
$section->add($group);
757

    
758
$section->addInput(new Form_Select(
759
	'pppoe-reset-type',
760
	'Periodic Reset',
761
	$pconfig['pppoe-reset-type'],
762
	array(
763
		'' => 'Disabled',
764
		'custom' => 'Custom',
765
		'preset' => 'Pre-set'
766
	)
767
))->addClass('pppoe')->setHelp('Select a reset timing type');
768

    
769
$group = new Form_Group('Rest Date/Time');
770
$group->addClass('pppoe-reset-date');
771

    
772
$group->add(new Form_Input(
773
	'pppoe_resethour',
774
	null,
775
	'text',
776
	$pconfig['pppoe_resethour']
777
))->setHelp('Hour');
778

    
779
$group->add(new Form_Input(
780
	'pppoe_resetminute',
781
	null,
782
	'text',
783
	$pconfig['pppoe_resetminute']
784
))->setHelp('Minute');
785

    
786
$group->add(new Form_Input(
787
	'pppoe_resetdate',
788
	null,
789
	'text',
790
	$pconfig['pppoe_resetdate'],
791
	['placeholder' => 'mm/dd/yyyy']
792
))->setHelp('Specific date');
793

    
794
$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. ');
795

    
796
$section->add($group);
797

    
798
$group = new Form_Group('Rest frequency');
799
$group->addClass('pppoe-reset-cron');
800

    
801
$group->add(new Form_Checkbox(
802
	'pppoe_pr_preset_val',
803
	null,
804
	'Monthly (0 0 1 * *)',
805
	$pconfig['pppoe_monthly'],
806
	'monthly'
807
))->displayAsRadio();
808

    
809
$group->add(new Form_Checkbox(
810
	'pppoe_pr_preset_val',
811
	null,
812
	'Weekly (0 0 * * 0)',
813
	$pconfig['pppoe_weekly'],
814
	'weekly'
815
))->displayAsRadio();
816

    
817
$group->add(new Form_Checkbox(
818
	'pppoe_pr_preset_val',
819
	null,
820
	'Daily (0 0 * * *)',
821
	$pconfig['pppoe_daily'],
822
	'daily'
823
))->displayAsRadio();
824

    
825
$group->add(new Form_Checkbox(
826
	'pppoe_pr_preset_val',
827
	null,
828
	'Hourly (0 * * * *)',
829
	$pconfig['pppoe_hourly'],
830
	'hourly'
831
))->displayAsRadio();
832

    
833
$section->add($group);
834

    
835
$btnadvanced = new Form_Button(
836
		'btnadvanced',
837
		'Show'
838
);
839

    
840
$btnadvanced->removeClass('btn-primary')->addClass('btn-default btn-sm');
841

    
842
$section->addInput(new Form_StaticText(
843
	'Advanced options',
844
	$btnadvanced
845
));
846

    
847
$form->add($section);
848

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

    
852
$section->addInput(new Form_Checkbox(
853
	'ondemand',
854
	'Dial On Demand',
855
	'Enable Dial-on-Demand mode. ',
856
	$pconfig['ondemand']
857
))->setHelp('Causes the interface to operate in dial-on-demand mode. Do NOT enable if you want your link to be always up. ' .
858
			'The interface is configured, but the actual connection of the link is delayed until qualifying outgoing traffic is detected.');
859

    
860
$section->addInput(new Form_Input(
861
	'idletimeout',
862
	'Idle Timeout',
863
	'text',
864
	$pconfig['idletimeout']
865
))->setHelp('If no incoming or outgoing packets are transmitted for the entered number of seconds the connection is brought down.' .
866
			'When the idle timeout occurs, if the dial-on-demand option is enabled, mpd goes back into dial-on-demand mode. ' .
867
			'Otherwise, the interface is brought down and all associated routes removed.');
868

    
869
$section->addInput(new Form_Checkbox(
870
	'vjcomp',
871
	'Compression',
872
	'Disable vjcomp (compression, auto-negotiated by default).',
873
	$pconfig['vjcomp']
874
))->setHelp('Disable vjcomp(compression) (auto-negotiated by default).' . '<br />' .
875
				'This option enables Van Jacobson TCP header compression, which saves several bytes per TCP data packet.' .
876
				'This option is almost always required. Compression is not effective for TCP connections with enabled modern extensions like time ' .
877
				'stamping or SACK, which modify TCP options between sequential packets.');
878

    
879
$section->addInput(new Form_Checkbox(
880
	'tcpmssfix',
881
	'TCPmssFix',
882
	'Disable tcpmssfix (enabled by default).',
883
	$pconfig['tcpmssfix']
884
))->setHelp('Causes mpd to adjust incoming and outgoing TCP SYN segments so that the requested maximum segment size is not greater than the amount ' .
885
			'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, ' .
886
			'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, ' .
887
			'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 ' .
888
			'gets to discover that it must reduce the fragment size or drop the IP Don\'t Fragment option from its outgoing data.');
889

    
890
$section->addInput(new Form_Checkbox(
891
	'shortseq',
892
	'ShortSeq',
893
	'Disable shortseq (auto-negotiated by default).',
894
	$pconfig['shortseq']
895
))->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. ' .
896
			'It is not necessary to disable this for connections that are not multi-link.');
897

    
898
$section->addInput(new Form_Checkbox(
899
	'acfcomp',
900
	'ACFComp',
901
	'Disable ACF compression (auto-negotiated by default)',
902
	$pconfig['acfcomp']
903
))->setHelp('Address and control field compression. This option only applies to asynchronous link types. It saves two bytes per frame.');
904

    
905
$section->addInput(new Form_Checkbox(
906
	'protocomp',
907
	'ProtoComp',
908
	'Disable Protocol compression (auto-negotiated by default)',
909
	$pconfig['protocomp']
910
))->setHelp('Protocol field compression. This option saves one byte per frame for most frames.');
911

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

    
915
foreach($linklist['list'] as $ifnm =>$nm) {
916

    
917
	$group = new Form_Group('Link Parameters (' . $ifnm . ')');
918

    
919
	$group->add(new Form_Input(
920
		'bandwidth' . $j,
921
		null,
922
		'text',
923
		$pconfig['bandwidth'][$j]
924
	))->setHelp('Bandwidth');
925

    
926
	$group->add(new Form_Input(
927
		'mtu' . $j,
928
		null,
929
		'password',
930
		$pconfig['mtu'][$j]
931
	))->setHelp('MTU');
932

    
933
	$group->add(new Form_Input(
934
		'mru' . $j,
935
		null,
936
		'password',
937
		$pconfig['mru'][$j]
938
	))->setHelp('MRU');
939

    
940
	$group->add(new Form_Input(
941
		'mrru' . $j,
942
		null,
943
		'password',
944
		$pconfig['mrru'][$j]
945
	))->setHelp('MRRU');
946

    
947
	$j++;
948

    
949
	$section->add($group);
950

    
951
	$group->addClass('localip sec-advanced')->addClass('linkparam' . $ifnm);
952
}
953

    
954
$linkparamhelp = new Form_StaticText(
955
	null,
956
	'<span id="linkparamhelp">' . $linkparamstr . '</span>'
957
);
958

    
959
$section->addInput($linkparamhelp);
960

    
961
if (isset($id) && $a_ppps[$id]) {
962
	$section->addInput(new Form_Input(
963
		'id',
964
		null,
965
		'hidden',
966
		$id
967
	));
968
}
969

    
970
$section->addInput(new Form_Input(
971
	'ptpid',
972
	null,
973
	'hidden',
974
	$ptpid
975
));
976

    
977
$form->add($section);
978

    
979
print($form);
980

    
981
?>
982

    
983
<script>
984
//<![CDATA[
985
events.push(function(){
986
	var showadvanced = false;
987

    
988
	// Hides the <div> in which the specified input element lives so that the input, its label and help text are hidden
989
	function hideInput(id, hide) {
990
		if(hide)
991
			$('#' + id).parent().parent('div').addClass('hidden');
992
		else
993
			$('#' + id).parent().parent('div').removeClass('hidden');
994
	}
995

    
996
	// Hides the <div> in which the specified checkbox lives so that the checkbox, its label and help text are hidden
997
	function hideCheckbox(id, hide) {
998
		if(hide)
999
			$('#' + id).parent().parent().parent('div').addClass('hidden');
1000
		else
1001
			$('#' + id).parent().parent().parent('div').removeClass('hidden');
1002
	}
1003

    
1004
	// Disables the specified input element
1005
	function disableInput(id, disable) {
1006
		$('#' + id).prop("disabled", disable);
1007
	}
1008

    
1009
	// Hides all elements of the specified class. This will usually be a section or group
1010
	function hideClass(s_class, hide) {
1011
		if(hide)
1012
			$('.' + s_class).hide();
1013
		else
1014
			$('.' + s_class).show();
1015
	}
1016

    
1017
	// Simple test in which clicking the ‘clear’ button toggles certain display elements
1018
	function setAdvVisible() {
1019
		// Update the button text and toggle showadvanced
1020
		if(showadvanced) {
1021
			$("#btnadvanced").prop('value', 'Hide');
1022
			showadvanced = false;
1023
		}
1024
		else {
1025
			$("#btnadvanced").prop('value', 'Show');
1026
			showadvanced = true;
1027
		}
1028

    
1029
		hideClass('sec-advanced', showadvanced);
1030

    
1031
		// The options that follow are only shown if type == 'ppp'
1032
		var ppptype = ($('#type').val() == 'ppp');
1033

    
1034
		hideInput('apnum', showadvanced && ppptype);
1035
		hideInput('simpin', showadvanced && ppptype);
1036
		hideInput('pin-wait', showadvanced && ppptype);
1037
		hideInput('initstr', showadvanced && ppptype);
1038
		hideInput('connect-timeout', showadvanced && ppptype);
1039
		hideCheckbox('uptime', showadvanced && ppptype);
1040

    
1041
		// The options that follow are only shown if type == 'pppoe'
1042
		var pppoetype = ($('#type').val() != 'pppoe');
1043

    
1044
		hideClass('pppoe', showadvanced || pppoetype);
1045
		hideInput('pppoe-reset-type', showadvanced || pppoetype);
1046

    
1047
		hideResetDisplay(true);
1048

    
1049
		hideInterfaces();
1050
	}
1051

    
1052
	function hideResetDisplay(hide) {
1053

    
1054
		hideClass('pppoe-reset-date', true);
1055
		hideClass('pppoe-reset-cron', true);
1056

    
1057
		if(!hide) {
1058
			switch($('#pppoe-reset-type').val()) {
1059
				case 'custom' :
1060
					hideClass('pppoe-reset-date', false);
1061
					break;
1062
				case 'preset' :
1063
					hideClass('pppoe-reset-cron', false);
1064
					break;
1065
			}
1066
		}
1067
	}
1068

    
1069
	function hideInterfaces() {
1070
		hideClass('localip', true);
1071
		hideClass('linkparam', true);
1072
		hideInput('linkparamhelp', true);
1073

    
1074
		var selected = $('.interfaces').val();
1075
		var length = selected.length;
1076

    
1077
		for(var i=0; i<length; i++) {
1078
			hideClass('localip' + selected[i], false);
1079

    
1080
			if(!showadvanced) {
1081
				hideClass('linkparam' + selected[i], false);
1082
				hideInput('linkparamhelp', false);
1083
			   }
1084
		}
1085
	}
1086

    
1087
	// Make the ‘btnadvanced’ button a plain button, not a submit button
1088
	$("#btnadvanced").prop('type','button');
1089

    
1090
	$("#btnadvanced").click(function() {
1091
		setAdvVisible();
1092
	});
1093

    
1094
	$('#pppoe-reset-type').on('change', function() {
1095
		hideResetDisplay(false);
1096
	});
1097

    
1098
	// When interfaces changed, read the selected items and unhide the corresponding IP/Gateway controls
1099
	// Multiselect boxes must be handled by class
1100
	$('.interfaces').on('change', function() {
1101
		hideInterfaces();
1102
	 });
1103

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

    
1109
	$('#country').on('change', function() {
1110
		window.location = 'interfaces_ppps_edit.php?id=' + $('#id').val() + '&country=' + this.value + '&type=' + $('#type').val();
1111
	});
1112

    
1113
	$('#provider').on('change', function() {
1114
		window.location = 'interfaces_ppps_edit.php?id=' + $('#id').val() + '&provider=' + this.value + '&type=' + $('#type').val() + '&country=' + $('#country').val();
1115
	});
1116

    
1117
	// Set element visibility on initial page load
1118
	setAdvVisible();
1119

    
1120
	hideClass('linkparam', true);
1121
});
1122
//]]>
1123

    
1124
</script>
1125
<?php
1126

    
1127
include("foot.inc");
(96-96/238)