Project

General

Profile

Download (17.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/*
3
	vpn_pppoe_edit.php
4
	part of pfSense
5

    
6
	Copyright (C) 2005 Scott Ullrich (sullrich@gmail.com)
7
	Copyright (C) 2010 Ermal Luçi
8
	Copyright (C) 2013-2015 Electric Sheep Fencing, LP
9
	All rights reserved.
10

    
11
	Redistribution and use in source and binary forms, with or without
12
	modification, are permitted provided that the following conditions are met:
13

    
14
	1. Redistributions of source code must retain the above copyright notice,
15
	   this list of conditions and the following disclaimer.
16

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

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

    
33
##|+PRIV
34
##|*IDENT=page-services-pppoeserver-edit
35
##|*NAME=Services: PPPoE Server: Edit page
36
##|*DESCR=Allow access to the 'Services: PPPoE Server: Edit' page.
37
##|*MATCH=vpn_pppoe_edit.php*
38
##|-PRIV
39

    
40
require("guiconfig.inc");
41
require_once("vpn.inc");
42
$addrow = false;
43
$dltrow = 9999;
44

    
45
function vpn_pppoe_get_id() {
46
	global $config;
47

    
48
	$vpnid = 1;
49
	if (is_array($config['pppoes']['pppoe'])) {
50
		foreach ($config['pppoes']['pppoe'] as $pppoe) {
51
			if ($vpnid == $pppoe['pppoeid'])
52
				$vpnid++;
53
			else
54
				return $vpnid;
55
		}
56
	}
57

    
58
	return $vpnid;
59
}
60

    
61
if (!is_array($config['pppoes']['pppoe'])) {
62
	$config['pppoes']['pppoe'] = array();
63
}
64

    
65
$a_pppoes = &$config['pppoes']['pppoe'];
66

    
67
if (is_numericint($_GET['id']))
68
	$id = $_GET['id'];
69

    
70
if($_GET['addrow'] == 'true')
71
	$addrow = true;
72

    
73
if (is_numericint($_GET['dltrow']))
74
	$dltrow = $_GET['dltrow'];
75

    
76
if (isset($_POST['id']) && is_numericint($_POST['id']))
77
	$id = $_POST['id'];
78

    
79
if (isset($id) && $a_pppoes[$id]) {
80
	$pppoecfg =& $a_pppoes[$id];
81

    
82
	$pconfig['remoteip'] = $pppoecfg['remoteip'];
83
	$pconfig['localip'] = $pppoecfg['localip'];
84
	$pconfig['mode'] = $pppoecfg['mode'];
85
	$pconfig['interface'] = $pppoecfg['interface'];
86
	$pconfig['n_pppoe_units'] = $pppoecfg['n_pppoe_units'];
87
	$pconfig['pppoe_subnet'] = $pppoecfg['pppoe_subnet'];
88
	$pconfig['pppoe_dns1'] = $pppoecfg['dns1'];
89
	$pconfig['pppoe_dns2'] = $pppoecfg['dns2'];
90
	$pconfig['descr'] = $pppoecfg['descr'];
91
	$pconfig['username'] = $pppoecfg['username'];
92
	$pconfig['pppoeid'] = $pppoecfg['pppoeid'];
93
	if (is_array($pppoecfg['radius'])) {
94
		$pconfig['radacct_enable'] = isset($pppoecfg['radius']['accounting']);
95
		$pconfig['radiusissueips'] = isset($pppoecfg['radius']['radiusissueips']);
96
		if (is_array($pppoecfg['radius']['server'])) {
97
			$pconfig['radiusenable'] = isset($pppoecfg['radius']['server']['enable']);
98
			$pconfig['radiusserver'] = $pppoecfg['radius']['server']['ip'];
99
			$pconfig['radiusserverport'] = $pppoecfg['radius']['server']['port'];
100
			$pconfig['radiusserveracctport'] = $pppoecfg['radius']['server']['acctport'];
101
			$pconfig['radiussecret'] = $pppoecfg['radius']['server']['secret'];
102
		}
103

    
104
		if (is_array($pppoecfg['radius']['server2'])) {
105
			$pconfig['radiussecenable'] = isset($pppoecfg['radius']['server2']['enable']);
106
			$pconfig['radiusserver2'] = $pppoecfg['radius']['server2']['ip'];
107
			$pconfig['radiusserver2port'] = $pppoecfg['radius']['server2']['port'];
108
			$pconfig['radiusserver2acctport'] = $pppoecfg['radius']['server2']['acctport'];
109
			$pconfig['radiussecret2'] = $pppoecfg['radius']['server2']['secret2'];
110
		}
111

    
112
		$pconfig['radius_nasip'] = $pppoecfg['radius']['nasip'];
113
		$pconfig['radius_acct_update'] = $pppoecfg['radius']['acct_update'];
114
	}
115
}
116

    
117
if ($_POST) {
118
	unset($input_errors);
119
	$pconfig = $_POST;
120

    
121
	/* input validation */
122
	if ($_POST['mode'] == "server") {
123
		$reqdfields = explode(" ", "localip remoteip");
124
		$reqdfieldsn = array(gettext("Server address"),gettext("Remote start address"));
125

    
126
		if ($_POST['radiusenable']) {
127
			$reqdfields = array_merge($reqdfields, explode(" ", "radiusserver radiussecret"));
128
			$reqdfieldsn = array_merge($reqdfieldsn,
129
				array(gettext("RADIUS server address"),gettext("RADIUS shared secret")));
130
		}
131

    
132
		do_input_validation($_POST, $reqdfields, $reqdfieldsn, $input_errors);
133

    
134
		if (($_POST['localip'] && !is_ipaddr($_POST['localip'])))
135
			$input_errors[] = gettext("A valid server address must be specified.");
136
		if (($_POST['pppoe_subnet'] && !is_ipaddr($_POST['remoteip'])))
137
			$input_errors[] = gettext("A valid remote start address must be specified.");
138
		if (($_POST['radiusserver'] && !is_ipaddr($_POST['radiusserver'])))
139
			$input_errors[] = gettext("A valid RADIUS server address must be specified.");
140

    
141
		$_POST['remoteip'] = $pconfig['remoteip'] = gen_subnet($_POST['remoteip'], $_POST['pppoe_subnet']);
142
		$subnet_start = ip2ulong($_POST['remoteip']);
143
		$subnet_end = ip2ulong($_POST['remoteip']) + $_POST['pppoe_subnet'] - 1;
144
		if ((ip2ulong($_POST['localip']) >= $subnet_start) &&
145
			(ip2ulong($_POST['localip']) <= $subnet_end))
146
			$input_errors[] = gettext("The specified server address lies in the remote subnet.");
147
		if ($_POST['localip'] == get_interface_ip($_POST['interface']))
148
			$input_errors[] = gettext("The specified server address is equal to an interface ip address.");
149

    
150
		for($x=0; $x<4999; $x++) {
151
			if ($_POST["username{$x}"]) {
152
				if (empty($_POST["password{$x}"]))
153
					$input_errors[] = sprintf(gettext("No password specified for username %s"),$_POST["username{$x}"]);
154
				if ($_POST["ip{$x}"] != "" && !is_ipaddr($_POST["ip{$x}"]))
155
					$input_errors[] = sprintf(gettext("Incorrect ip address	 specified for username %s"),$_POST["username{$x}"]);
156
			}
157
		}
158
	}
159

    
160
	if ($_POST['pppoeid'] && !is_numeric($_POST['pppoeid']))
161
		$input_errors[] = gettext("Wrong data submitted");
162

    
163
	if (!$input_errors) {
164
		$pppoecfg = array();
165

    
166
		$pppoecfg['remoteip'] = $_POST['remoteip'];
167
		$pppoecfg['localip'] = $_POST['localip'];
168
		$pppoecfg['mode'] = $_POST['mode'];
169
		$pppoecfg['interface'] = $_POST['interface'];
170
		$pppoecfg['n_pppoe_units'] = $_POST['n_pppoe_units'];
171
		$pppoecfg['pppoe_subnet'] = $_POST['pppoe_subnet'];
172
		$pppoecfg['descr'] = $_POST['descr'];
173
		if ($_POST['radiusserver'] || $_POST['radiusserver2']) {
174
			$pppoecfg['radius'] = array();
175

    
176
			$pppoecfg['radius']['nasip'] = $_POST['radius_nasip'];
177
			$pppoecfg['radius']['acct_update'] = $_POST['radius_acct_update'];
178
		}
179

    
180
		if ($_POST['radiusserver']) {
181
			$pppoecfg['radius']['server'] = array();
182

    
183
			$pppoecfg['radius']['server']['ip'] = $_POST['radiusserver'];
184
			$pppoecfg['radius']['server']['secret'] = $_POST['radiussecret'];
185
			$pppoecfg['radius']['server']['port'] = $_POST['radiusserverport'];
186
			$pppoecfg['radius']['server']['acctport'] = $_POST['radiusserveracctport'];
187
		}
188

    
189
		if ($_POST['radiusserver2']) {
190
			$pppoecfg['radius']['server2'] = array();
191

    
192
			$pppoecfg['radius']['server2']['ip'] = $_POST['radiusserver2'];
193
			$pppoecfg['radius']['server2']['secret2'] = $_POST['radiussecret2'];
194
			$pppoecfg['radius']['server2']['port'] = $_POST['radiusserver2port'];
195
			$pppoecfg['radius']['server2']['acctport'] = $_POST['radiusserver2acctport'];
196
		}
197

    
198
		if ($_POST['pppoe_dns1'] != "")
199
			$pppoecfg['dns1'] = $_POST['pppoe_dns1'];
200

    
201
		if ($_POST['pppoe_dns2'] != "")
202
			$pppoecfg['dns2'] = $_POST['pppoe_dns2'];
203

    
204
		if($_POST['radiusenable'] == "yes")
205
			$pppoecfg['radius']['server']['enable'] = true;
206

    
207
		if($_POST['radiussecenable'] == "yes")
208
			$pppoecfg['radius']['server2']['enable'] = true;
209

    
210
		if($_POST['radacct_enable'] == "yes")
211
			$pppoecfg['radius']['accounting'] = true;
212

    
213
		if($_POST['radiusissueips'] == "yes")
214
			$pppoecfg['radius']['radiusissueips'] = true;
215

    
216
		if($_POST['pppoeid'])
217
			$pppoecfg['pppoeid'] = $_POST['pppoeid'];
218
		else
219
			$pppoecfg['pppoeid'] = vpn_pppoe_get_id();
220

    
221
		$users = array();
222
		for($x=0; $x<4999; $x++) {
223
			if ($_POST["username{$x}"]) {
224
				$usernam = $_POST["username{$x}"] . ":" . base64_encode($_POST["password{$x}"]);
225
				if ($_POST["ip{$x}"])
226
					$usernam .= ":" . $_POST["ip{$x}"];
227
				$users[] = $usernam;
228
			}
229
		}
230

    
231
		if (count($users) > 0)
232
			$pppoecfg['username'] = implode(" ", $users);
233

    
234
		if (!isset($id))
235
			$id = count($a_pppoes);
236

    
237
		if (file_exists("{$g['tmp_path']}/.vpn_pppoe.apply"))
238
			$toapplylist = unserialize(file_get_contents("{$g['tmp_path']}/.vpn_pppoe.apply"));
239
		else
240
			$toapplylist = array();
241

    
242
		$toapplylist[] = $pppoecfg['pppoeid'];
243
		$a_pppoes[$id] = $pppoecfg;
244

    
245
		write_config();
246
		mark_subsystem_dirty('vpnpppoe');
247
		file_put_contents("{$g['tmp_path']}/.vpn_pppoe.apply", serialize($toapplylist));
248
		header("Location: vpn_pppoe.php");
249
		exit;
250
	}
251
}
252

    
253
function build_interface_list() {
254
	$list = array();
255

    
256
	$interfaces = get_configured_interface_with_descr();
257

    
258
	foreach ($interfaces as $iface => $ifacename)
259
		$list[$iface] = $ifacename;
260

    
261
	return($list);
262
}
263

    
264
$pgtitle = array(gettext("Services"),gettext("PPPoE Server"), gettext("Edit"));
265
$shortcut_section = "pppoes";
266
include("head.inc");
267

    
268
if ($input_errors)
269
	print_input_errors($input_errors);
270

    
271
if ($savemsg)
272
	print_info_box($savemsg, 'success');
273

    
274
require('classes/Form.class.php');
275

    
276
$form = new Form();
277

    
278
$section = new Form_Section('PPPoE Server Configuration');
279

    
280
$section->addInput(new Form_Checkbox(
281
	'mode',
282
	'Enable',
283
	'Enable PPPoE Server',
284
	($pconfig['mode'] == "server")
285
)) ->toggles('.form-group:not(:first-child)');
286

    
287
$section->addInput(new Form_Select(
288
	'interface',
289
	'Interface',
290
	$pconfig['interface'],
291
	build_interface_list()
292

    
293
));
294

    
295
$section->addInput(new Form_Select(
296
	'pppoe_subnet',
297
	'Subnet netask',
298
	$pconfig['pppoe_subnet'],
299
	array_combine(range(0, 32, 1), range(0, 32, 1))
300
))->setHelp('Hint: 24 is 255.255.255.0');
301

    
302
$section->addInput(new Form_Select(
303
	'n_pppoe_units',
304
	'No. of PPPoE Users',
305
	$pconfig['n_pppoe_units'],
306
	array_combine(range(0, 255, 1), range(0, 255, 1))
307
));
308

    
309
$section->addInput(new Form_IpAddress(
310
	'localip',
311
	'Server Address',
312
	$pconfig['localip']
313
))->setHelp('Enter the IP address the PPPoE server should give to clients for use as their "gateway"' . '<br />' .
314
			'Typically this is set to an unused IP just outside of the client range '. '<br />' .
315
			'NOTE: This should NOT be set to any IP address currently in use on this firewall');
316

    
317
$section->addInput(new Form_IpAddress(
318
	'remoteip',
319
	'Remote Address Range',
320
	$pconfig['remoteip']
321
))->setHelp('Specify the starting address for the client IP address subnet');
322

    
323
$section->addInput(new Form_Input(
324
	'descr',
325
	'Description',
326
	'text',
327
	$pconfig['descr']
328
));
329

    
330
$section->addInput(new Form_Input(
331
	'pppoe_dns1',
332
	'DNS Servers',
333
	'text',
334
	$pconfig['pppoe_dns1']
335
));
336

    
337
$section->addInput(new Form_IpAddress(
338
	'pppoe_dns2',
339
	null,
340
	$pconfig['pppoe_dns2']
341
))->setHelp('If entered these servers will be given to all PPPoE clients, otherwise LAN DNS and one WAN DNS will go to all clients');
342

    
343
$section->addInput(new Form_Checkbox(
344
	'radiusenable',
345
	'RADIUS',
346
	'Use a Radius Server for authentication',
347
	$pconfig['radiusenable']
348
))->setHelp('All users will be authenticated using the RADIUS server specified below. The local user database ' .
349
			'will not be used');
350

    
351
$section->addInput(new Form_Checkbox(
352
	'radacct_enable',
353
	null,
354
	'Enable Radius Accounting',
355
	$pconfig['radacct_enable']
356
))->setHelp('Sends accounting packets to the RADIUS server');
357

    
358
$section->addInput(new Form_Checkbox(
359
	'radiussecenable',
360
	null,
361
	'Use backup RADIUS server',
362
	$pconfig['radiussecenable']
363
))->setHelp('If primary server fails all requests will be sent via backup server');
364

    
365
$section->addInput(new Form_IpAddress(
366
	'radius_nasip',
367
	'NAS IP Address',
368
	$pconfig['radius_nasip']
369
))->setHelp('RADIUS server NAS IP Address');
370

    
371
$section->addInput(new Form_Input(
372
	'radius_acct_update',
373
	'RADIUS Accounting Update',
374
	'text',
375
	$pconfig['radius_acct_update']
376
))->setHelp('RADIUS accounting update period in seconds');
377

    
378
$section->addInput(new Form_Checkbox(
379
	'radiusissueips',
380
	'Radius Issued IPs',
381
	'Issue IP Addresses via RADIUS server',
382
	$pconfig['radiusissueips']
383
));
384

    
385
$group = new Form_Group('RADIUS server Primary');
386

    
387
$group->add(new Form_IpAddress(
388
	'radiusserver',
389
	null,
390
	$pconfig['radiusserver']
391
))->setHelp('IP Address');
392

    
393
$group->add(new Form_Input(
394
	'radiusserverport',
395
	null,
396
	'text',
397
	$pconfig['radiusserverport']
398
))->setHelp('Authentication port ');
399

    
400
$group->add(new Form_Input(
401
	'radiusserveracctport',
402
	null,
403
	'text',
404
	$pconfig['radiusserveracctport']
405
))->setHelp('Accounting port (optional)');
406

    
407
$group->setHelp('Standard ports are 1812 (authentication) and 1813 (accounting)');
408

    
409
$section->add($group);
410

    
411
$section->addInput(new Form_Input(
412
	'radiussecret',
413
	'RADIUS primary shared secret',
414
	'password',
415
	$pconfig['radiussecret']
416
))->setHelp('Enter the shared secret that will be used to authenticate to the RADIUS server.');
417

    
418
$group = new Form_Group('RADIUS server Secondary');
419

    
420
$group->add(new Form_IpAddress(
421
	'radiusserver2',
422
	null,
423
	$pconfig['radiusserver2']
424
))->setHelp('IP Address');
425

    
426
$group->add(new Form_Input(
427
	'radiusserver2port',
428
	null,
429
	'text',
430
	$pconfig['radiusserver2port']
431
))->setHelp('Authentication port ');
432

    
433
$group->add(new Form_Input(
434
	'radiusserver2acctport',
435
	null,
436
	'text',
437
	$pconfig['radiusserver2acctport']
438
))->setHelp('Accounting port (optional)');
439

    
440
$group->setHelp('Standard ports are 1812 (authentication) and 1813 (accounting)');
441

    
442
$section->add($group);
443

    
444
$section->addInput(new Form_Input(
445
	'radiussecret2',
446
	'RADIUS secondary shared secret',
447
	'password',
448
	$pconfig['radiussecret2']
449
))->setHelp('Enter the shared secret that will be used to authenticate to the backup RADIUS server.');
450

    
451
$counter = 0;
452
$usernames = $pconfig['username'];
453

    
454
//DEBUG
455
$usernames = 'sbeaver:TXlQYXNzd2Q=:192.168.1.1 smith:TXlQYXNzd2Q=:192.168.2.1 sjones:TXlQYXNzd2Q=:192.168.3.1 salpha:TXlQYXNzd2Q=:192.168.4.1';
456

    
457
if($addrow)
458
	$usernames .= ' ::';
459

    
460
if ($usernames != ""):
461
	$item = explode(" ", $usernames);
462

    
463
	$numrows = count($item) -1;
464

    
465
	foreach($item as $ww):
466
		$wws = explode(":", $ww);
467
		$user = $wws[0];
468
		$passwd = base64_decode($wws[1]);
469
		$ip = $wws[2];
470

    
471
		$tracker = $counter;
472

    
473
		if($tracker != $dltrow) {
474
			$group = new Form_Group($counter == 0 ? 'User table':null);
475

    
476
			$group->add(new Form_Input(
477
				'username' . $tracker,
478
				null,
479
				'text',
480
				$user
481
			))->setHelp($numrows == $tracker ? 'User name':null);
482

    
483
			$group->add(new Form_Input(
484
				'password' . $tracker,
485
				null,
486
				'password',
487
				$passwd
488
			))->setHelp($numrows == $tracker ? 'Password':null);
489

    
490
			$group->add(new Form_IpAddress(
491
				'ip' . $tracker,
492
				null,
493
				$ip
494
			))->setHelp($numrows == $tracker ? 'IP Address':null);
495

    
496
			$btndltrow = new Form_Button(
497
				'btndltrow' . $tracker,
498
				'Delete',
499
				'vpn_pppoe_edit.php?id=' . $id . '&dltrow=' . $tracker
500
			);
501

    
502
			$btndltrow->removeClass('btn-primary')->addClass('btn-danger btn-sm');
503

    
504
			$group->add($btndltrow);
505
			$section->add($group);
506
		}
507

    
508
		$counter++;
509
	endforeach;
510
endif;
511

    
512
$btnaddrow = new Form_Button(
513
	'btnaddrow',
514
	'Add Row',
515
	'vpn_pppoe_edit.php?id=' . $id . '&addrow=true'
516
	);
517

    
518
$btnaddrow->removeClass('btn-primary')->addClass('btn-success btn-sm');
519

    
520
$section->addInput($btnaddrow);
521

    
522
// Hidden fields
523
if(isset($id)) {
524
	$section->addInput(new Form_Input(
525
		'id',
526
		null,
527
		'hidden',
528
		htmlspecialchars($id, ENT_QUOTES | ENT_HTML401)
529
	));
530
}
531

    
532
if (isset($pconfig['pppoeid'])) {
533
	$section->addInput(new Form_Input(
534
		'pppoeid',
535
		null,
536
		'hidden',
537
		$pconfig['pppoeid']
538
	));
539
}
540

    
541
$form->add($section);
542

    
543
$form->addGlobal(new Form_Button(
544
	'cancel',
545
	'Cancel',
546
	'vpn_pppoe.php'
547
))->removeClass('btn-primary')->addClass('btn-default');
548

    
549
print($form);
550

    
551
print_info_box(gettext('Don\'t forget to add a firewall rule to permit traffic from PPPoE clients'));
552
?>
553
<script>
554
//<![CDATA[
555
events.push(function(){
556

    
557
	// Disables the specified input element
558
	function disableInput(id, disable) {
559
		$('#' + id).prop("disabled", disable);
560
	}
561

    
562
	// show/hide radius server controls
563
	function hide_radius(hide) {
564
		disableInput('radacct_enable', hide);
565
		disableInput('radiusserver', hide);
566
		disableInput('radiussecret', hide);
567
		disableInput('radiusserverport', hide);
568
		disableInput('radiusserveracctport', hide);
569
		disableInput('radiusissueips', hide);
570
		disableInput('radius_nasip', hide);
571
		disableInput('radiusissueips', hide);
572
		disableInput('radius_nasip', hide);
573
		disableInput('radius_acct_update', hide);
574
		disableInput('radiussecenable', hide);
575
		hide_radius2(hide);
576
	}
577
	// show/hide radius server 2 controls
578
	function hide_radius2(hide) {
579
		disableInput('radiusserver2', hide);
580
		disableInput('radiussecret2', hide);
581
		disableInput('radiusserver2port', hide);
582
		disableInput('radiusserver2acctport', hide);
583
	}
584

    
585
	// When the RADIUS checkbox is clicked . .
586
	$('#radiusenable').click(function () {
587
		hide_radius(!$('#radiusenable').prop('checked'));
588
		if(!$('#radiusenable').prop('checked'))
589
			hide_radius2(true);
590
		else
591
			hide_radius2(!$('#radiussecenable').prop('checked'));
592
	});
593

    
594
	// When the 'Use backup RADIUS' checkbox is clicked . .
595
	$('#radiussecenable').click(function () {
596
		hide_radius2(!$('#radiussecenable').prop('checked'));
597
	});
598

    
599
	//I On initial page load
600
	hide_radius2(!$('#radiussecenable').prop('checked'));
601
	hide_radius(!$('#radiusenable').prop('checked'));
602
});
603
//]]>
604
</script>
605
<?php
606
include("foot.inc");
(236-236/241)