Project

General

Profile

Download (104 KB) Statistics
| Branch: | Tag: | Revision:
1 14227c51 Scott Ullrich
<?php
2 09221bc3 Renato Botelho
/*
3 ac24dc24 Renato Botelho
 * pfsense-utils.inc
4
 *
5
 * part of pfSense (https://www.pfsense.org)
6 38809d47 Renato Botelho do Couto
 * Copyright (c) 2004-2013 BSD Perimeter
7
 * Copyright (c) 2013-2016 Electric Sheep Fencing
8 402c98a2 Reid Linnemann
 * Copyright (c) 2014-2023 Rubicon Communications, LLC (Netgate)
9 ac24dc24 Renato Botelho
 * All rights reserved.
10
 *
11 b12ea3fb Renato Botelho
 * Licensed under the Apache License, Version 2.0 (the "License");
12
 * you may not use this file except in compliance with the License.
13
 * You may obtain a copy of the License at
14 ac24dc24 Renato Botelho
 *
15 b12ea3fb Renato Botelho
 * http://www.apache.org/licenses/LICENSE-2.0
16 ac24dc24 Renato Botelho
 *
17 b12ea3fb Renato Botelho
 * Unless required by applicable law or agreed to in writing, software
18
 * distributed under the License is distributed on an "AS IS" BASIS,
19
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
20
 * See the License for the specific language governing permissions and
21
 * limitations under the License.
22 ac24dc24 Renato Botelho
 */
23 3076becf Scott Ullrich
24 364c9484 Reid Linnemann
require_once("config.inc");
25
require_once("config.lib.inc");
26
27 0397013a Scott Ullrich
/****f* pfsense-utils/have_natpfruleint_access
28
 * NAME
29
 *   have_natpfruleint_access
30
 * INPUTS
31 c96e71d1 Renato Botelho
 *	none
32 0397013a Scott Ullrich
 * RESULT
33
 *   returns true if user has access to edit a specific firewall nat port forward interface
34
 ******/
35
function have_natpfruleint_access($if) {
36
	$security_url = "firewall_nat_edit.php?if=". strtolower($if);
37 c239afac Reid Linnemann
	if (isAllowedPage($security_url)) {
38 0397013a Scott Ullrich
		return true;
39 23a193da Phil Davis
	}
40 0397013a Scott Ullrich
	return false;
41
}
42
43 b6742927 Scott Ullrich
/****f* pfsense-utils/have_ruleint_access
44
 * NAME
45
 *   have_ruleint_access
46
 * INPUTS
47 c96e71d1 Renato Botelho
 *	none
48 b6742927 Scott Ullrich
 * RESULT
49
 *   returns true if user has access to edit a specific firewall interface
50
 ******/
51
function have_ruleint_access($if) {
52
	$security_url = "firewall_rules.php?if=". strtolower($if);
53 23a193da Phil Davis
	if (isAllowedPage($security_url)) {
54 45ee90ed Matthew Grooms
		return true;
55 23a193da Phil Davis
	}
56 b6742927 Scott Ullrich
	return false;
57
}
58
59 10387862 Scott Ullrich
/****f* pfsense-utils/does_url_exist
60
 * NAME
61
 *   does_url_exist
62
 * INPUTS
63 c96e71d1 Renato Botelho
 *	none
64 10387862 Scott Ullrich
 * RESULT
65
 *   returns true if a url is available
66
 ******/
67
function does_url_exist($url) {
68 4de8f7ba Phil Davis
	$fd = fopen("$url", "r");
69 23a193da Phil Davis
	if ($fd) {
70 4cc6345e Scott Ullrich
		fclose($fd);
71 5fa78adc Renato Botelho
		return true;
72 10387862 Scott Ullrich
	} else {
73 5fa78adc Renato Botelho
		return false;
74 10387862 Scott Ullrich
	}
75
}
76
77 5928bd75 Scott Ullrich
/****f* pfsense-utils/is_private_ip
78
 * NAME
79
 *   is_private_ip
80
 * INPUTS
81 c96e71d1 Renato Botelho
 *	none
82 5928bd75 Scott Ullrich
 * RESULT
83
 *   returns true if an ip address is in a private range
84
 ******/
85
function is_private_ip($iptocheck) {
86 5fa78adc Renato Botelho
	$isprivate = false;
87 4de8f7ba Phil Davis
	$ip_private_list = array(
88 5fa78adc Renato Botelho
		"10.0.0.0/8",
89
		"100.64.0.0/10",
90
		"172.16.0.0/12",
91
		"192.168.0.0/16",
92
	);
93 23a193da Phil Davis
	foreach ($ip_private_list as $private) {
94 4de8f7ba Phil Davis
		if (ip_in_subnet($iptocheck, $private) == true) {
95 5fa78adc Renato Botelho
			$isprivate = true;
96 23a193da Phil Davis
		}
97 5fa78adc Renato Botelho
	}
98
	return $isprivate;
99 5928bd75 Scott Ullrich
}
100
101 8cb370b9 Scott Ullrich
/****f* pfsense-utils/get_tmp_file
102
 * NAME
103
 *   get_tmp_file
104
 * INPUTS
105 c96e71d1 Renato Botelho
 *	none
106 8cb370b9 Scott Ullrich
 * RESULT
107
 *   returns a temporary filename
108
 ******/
109 3076becf Scott Ullrich
function get_tmp_file() {
110 da17d77e Ermal Lu?i
	global $g;
111
	return "{$g['tmp_path']}/tmp-" . time();
112 3076becf Scott Ullrich
}
113
114 f0c51530 jim-p
/* Stub for deprecated function
115
 * See https://redmine.pfsense.org/issues/10931 */
116 3076becf Scott Ullrich
function get_dns_servers() {
117 f0c51530 jim-p
	return get_dns_nameservers(false, true);
118 3076becf Scott Ullrich
}
119
120 c35d1294 doktornotor
/****f* pfsense-utils/pfSenseHeader
121
 * NAME
122
 *   pfSenseHeader
123
 * INPUTS
124
 *   none
125
 * RESULT
126 4864d7f6 Josh Soref
 *   JavaScript header change or browser Location:
127 c35d1294 doktornotor
 ******/
128
function pfSenseHeader($text) {
129
	global $_SERVER;
130
	if (isAjax()) {
131
		if ($_SERVER['HTTPS'] == "on") {
132
			$protocol = "https";
133
		} else {
134
			$protocol = "http";
135
		}
136
137
		$port = ":{$_SERVER['SERVER_PORT']}";
138
		if ($_SERVER['SERVER_PORT'] == "80" && $protocol == "http") {
139
			$port = "";
140
		}
141
		if ($_SERVER['SERVER_PORT'] == "443" && $protocol == "https") {
142
			$port = "";
143
		}
144
		$complete_url = "{$protocol}://{$_SERVER['HTTP_HOST']}{$port}/{$text}";
145
		echo "\ndocument.location.href = '{$complete_url}';\n";
146
	} else {
147
		header("Location: $text");
148
	}
149
}
150
151 8bab524e Phil Davis
/****f* pfsense-utils/get_css_files
152
 * NAME
153
 *   get_css_files - get a list of the available CSS files (themes)
154
 * INPUTS
155
 *   none
156
 * RESULT
157
 *   $csslist - an array of the CSS files
158
 ******/
159
function get_css_files() {
160
	$csslist = array();
161
162
	// List pfSense files, then any BETA files followed by any user-contributed files
163
	$cssfiles = glob("/usr/local/www/css/*.css");
164
165
	if (is_array($cssfiles)) {
166
		arsort($cssfiles);
167
		$usrcss = $pfscss = $betacss = array();
168
169
		foreach ($cssfiles as $css) {
170 cc2187c3 Renato Botelho
			// Don't display any login/logo page related CSS files
171
			if (strpos($css, "login") == 0 &&
172
			    strpos($css, "logo") == 0) {
173 7f4b697f Steve Beaver
				if (strpos($css, "BETA") != 0) {
174
					array_push($betacss, $css);
175
				} else if (strpos($css, "pfSense") != 0) {
176
					array_push($pfscss, $css);
177
				} else {
178
					array_push($usrcss, $css);
179
				}
180 8bab524e Phil Davis
			}
181
		}
182
183
		$css = array_merge($pfscss, $betacss, $usrcss);
184
185
		foreach ($css as $file) {
186
			$file = basename($file);
187
			$csslist[$file] = pathinfo($file, PATHINFO_FILENAME);
188
		}
189
	}
190
	return $csslist;
191
}
192
193
/****f* pfsense-utils/gen_webguicss_field
194
 * NAME
195
 *   gen_webguicss_field
196
 * INPUTS
197
 *   Pointer to section object
198
 *   Initial value for the field
199
 * RESULT
200
 *   no return value, section object is updated
201
 ******/
202
function gen_webguicss_field(&$section, $value) {
203
204
	$csslist = get_css_files();
205
206
	if (!isset($csslist[$value])) {
207
		$value = "pfSense.css";
208
	}
209
210
	$section->addInput(new Form_Select(
211
		'webguicss',
212
		'Theme',
213
		$value,
214
		$csslist
215 314a088a Phil Davis
	))->setHelp('Choose an alternative css file (if installed) to change the appearance of the webConfigurator. css files are located in /usr/local/www/css/%s', '<span id="csstxt"></span>');
216 8bab524e Phil Davis
}
217 9ceace25 jim-p
function validate_webguicss_field(&$input_errors, $value) {
218
	$csslist = get_css_files();
219
	if (!isset($csslist[$value])) {
220
		$input_errors[] = gettext("The submitted Theme could not be found. Pick a different theme.");
221
	}
222
}
223 8bab524e Phil Davis
224
/****f* pfsense-utils/gen_webguifixedmenu_field
225
 * NAME
226
 *   gen_webguifixedmenu_field
227
 * INPUTS
228
 *   Pointer to section object
229
 *   Initial value for the field
230
 * RESULT
231
 *   no return value, section object is updated
232
 ******/
233
function gen_webguifixedmenu_field(&$section, $value) {
234
235
	$section->addInput(new Form_Select(
236
		'webguifixedmenu',
237
		'Top Navigation',
238
		$value,
239
		["" => gettext("Scrolls with page"), "fixed" => gettext("Fixed (Remains visible at top of page)")]
240
	))->setHelp("The fixed option is intended for large screens only.");
241
}
242 9ceace25 jim-p
function validate_webguifixedmenu_field(&$input_errors, $value) {
243
	$valid_values = array("", "fixed");
244
	if (!in_array($value, $valid_values)) {
245
		$input_errors[] = gettext("The submitted Top Navigation value is invalid.");
246
	}
247
}
248 8bab524e Phil Davis
249
/****f* pfsense-utils/gen_webguihostnamemenu_field
250
 * NAME
251
 *   gen_webguihostnamemenu_field
252
 * INPUTS
253
 *   Pointer to section object
254
 *   Initial value for the field
255
 * RESULT
256
 *   no return value, section object is updated
257
 ******/
258
function gen_webguihostnamemenu_field(&$section, $value) {
259
260
	$section->addInput(new Form_Select(
261
		'webguihostnamemenu',
262
		'Hostname in Menu',
263
		$value,
264
		["" => gettext("Default (No hostname)"), "hostonly" => gettext("Hostname only"), "fqdn" => gettext("Fully Qualified Domain Name")]
265
	))->setHelp("Replaces the Help menu title in the Navbar with the system hostname or FQDN.");
266
}
267 9ceace25 jim-p
function validate_webguihostnamemenu_field(&$input_errors, $value) {
268
	$valid_values = array("", "hostonly", "fqdn");
269
	if (!in_array($value, $valid_values)) {
270
		$input_errors[] = gettext("The submitted Hostname in Menu value is invalid.");
271
	}
272
}
273 8bab524e Phil Davis
274
/****f* pfsense-utils/gen_dashboardcolumns_field
275
 * NAME
276
 *   gen_dashboardcolumns_field
277
 * INPUTS
278
 *   Pointer to section object
279
 *   Initial value for the field
280
 * RESULT
281
 *   no return value, section object is updated
282
 ******/
283
function gen_dashboardcolumns_field(&$section, $value) {
284
285 9ceace25 jim-p
	if (((int) $value < 1) || ((int) $value > 6)) {
286 8bab524e Phil Davis
		$value = 2;
287
	}
288
289
	$section->addInput(new Form_Input(
290
		'dashboardcolumns',
291
		'Dashboard Columns',
292
		'number',
293
		$value,
294 33d28154 Steve Beaver
		['min' => 1, 'max' => 6]
295 8bab524e Phil Davis
	));
296
}
297 9ceace25 jim-p
function validate_dashboardcolumns_field(&$input_errors, $value) {
298
	if (!is_numericint($value) || ((int) $value < 1) || ((int) $value > 6)) {
299
		$input_errors[] = gettext("The submitted Dashboard Columns value is invalid.");
300
	}
301
}
302 8bab524e Phil Davis
303 1d3510cf Phil Davis
/****f* pfsense-utils/gen_interfacessort_field
304
 * NAME
305
 *   gen_interfacessort_field
306
 * INPUTS
307
 *   Pointer to section object
308
 *   Initial value for the field
309
 * RESULT
310
 *   no return value, section object is updated
311
 ******/
312
function gen_interfacessort_field(&$section, $value) {
313
314
	$section->addInput(new Form_Checkbox(
315
		'interfacessort',
316
		'Interfaces Sort',
317
		'Sort Alphabetically',
318
		$value
319
	))->setHelp('If selected, lists of interfaces will be sorted by description, otherwise they are listed wan,lan,optn...');
320
}
321
322 8bab524e Phil Davis
/****f* pfsense-utils/gen_associatedpanels_fields
323
 * NAME
324
 *   gen_associatedpanels_fields
325
 * INPUTS
326
 *   Pointer to section object
327
 *   Initial value for each of the fields
328
 * RESULT
329
 *   no return value, section object is updated
330
 ******/
331
function gen_associatedpanels_fields(&$section, $value1, $value2, $value3, $value4) {
332
333
	$group = new Form_Group('Associated Panels Show/Hide');
334
335
	$group->add(new Form_Checkbox(
336
		'dashboardavailablewidgetspanel',
337
		null,
338
		'Available Widgets',
339
		$value1
340
		))->setHelp('Show the Available Widgets panel on the Dashboard.');
341
342
	$group->add(new Form_Checkbox(
343
		'systemlogsfilterpanel',
344
		null,
345
		'Log Filter',
346
		$value2
347
	))->setHelp('Show the Log Filter panel in System Logs.');
348
349
	$group->add(new Form_Checkbox(
350
		'systemlogsmanagelogpanel',
351
		null,
352
		'Manage Log',
353
		$value3
354
	))->setHelp('Show the Manage Log panel in System Logs.');
355
356
	$group->add(new Form_Checkbox(
357
		'statusmonitoringsettingspanel',
358
		null,
359
		'Monitoring Settings',
360
		$value4
361
	))->setHelp('Show the Settings panel in Status Monitoring.');
362
363
	$group->setHelp('These options allow certain panels to be automatically hidden on page load. A control is provided in the title bar to un-hide the panel.');
364
365
	$section->add($group);
366
}
367
368
/****f* pfsense-utils/gen_webguileftcolumnhyper_field
369
 * NAME
370
 *   gen_webguileftcolumnhyper_field
371
 * INPUTS
372
 *   Pointer to section object
373
 *   Initial value for the field
374
 * RESULT
375
 *   no return value, section object is updated
376
 ******/
377
function gen_webguileftcolumnhyper_field(&$section, $value) {
378
379
	$section->addInput(new Form_Checkbox(
380
		'webguileftcolumnhyper',
381
		'Left Column Labels',
382
		'Active',
383
		$value
384
	))->setHelp('If selected, clicking a label in the left column will select/toggle the first item of the group.');
385
}
386
387 d9058974 Phil Davis
/****f* pfsense-utils/gen_disablealiaspopupdetail_field
388
 * NAME
389
 *   gen_disablealiaspopupdetail_field
390
 * INPUTS
391
 *   Pointer to section object
392
 *   Initial value for the field
393
 * RESULT
394
 *   no return value, section object is updated
395
 ******/
396
function gen_disablealiaspopupdetail_field(&$section, $value) {
397
398
	$section->addInput(new Form_Checkbox(
399
		'disablealiaspopupdetail',
400
		'Alias Popups',
401
		'Disable details in alias popups',
402
		$value
403
	))->setHelp('If selected, the details in alias popups will not be shown, just the alias description (e.g. in Firewall Rules).');
404
}
405
406 8bab524e Phil Davis
/****f* pfsense-utils/gen_pagenamefirst_field
407
 * NAME
408
 *   gen_pagenamefirst_field
409
 * INPUTS
410
 *   Pointer to section object
411
 *   Initial value for the field
412
 * RESULT
413
 *   no return value, section object is updated
414
 ******/
415
function gen_pagenamefirst_field(&$section, $value) {
416
417
	$section->addInput(new Form_Checkbox(
418
		'pagenamefirst',
419
		'Browser tab text',
420
		'Display page name first in browser tab',
421
		$value
422
	))->setHelp('When this is unchecked, the browser tab shows the host name followed '.
423
		'by the current page. Check this box to display the current page followed by the '.
424
		'host name.');
425
}
426
427
/****f* pfsense-utils/gen_user_settings_fields
428
 * NAME
429
 *   gen_user_settings_fields
430
 * INPUTS
431
 *   Pointer to section object
432
 *   Array of initial values for the fields
433
 * RESULT
434
 *   no return value, section object is updated
435
 ******/
436
function gen_user_settings_fields(&$section, $pconfig) {
437
438
	gen_webguicss_field($section, $pconfig['webguicss']);
439
	gen_webguifixedmenu_field($section, $pconfig['webguifixedmenu']);
440
	gen_webguihostnamemenu_field($section, $pconfig['webguihostnamemenu']);
441
	gen_dashboardcolumns_field($section, $pconfig['dashboardcolumns']);
442 1d3510cf Phil Davis
	gen_interfacessort_field($section, $pconfig['interfacessort']);
443 8bab524e Phil Davis
	gen_associatedpanels_fields(
444
		$section,
445
		$pconfig['dashboardavailablewidgetspanel'],
446
		$pconfig['systemlogsfilterpanel'],
447
		$pconfig['systemlogsmanagelogpanel'],
448
		$pconfig['statusmonitoringsettingspanel']);
449
	gen_webguileftcolumnhyper_field($section, $pconfig['webguileftcolumnhyper']);
450 d9058974 Phil Davis
	gen_disablealiaspopupdetail_field($section, $pconfig['disablealiaspopupdetail']);
451 8bab524e Phil Davis
	gen_pagenamefirst_field($section, $pconfig['pagenamefirst']);
452
}
453
454 88081ea2 derelict-pf
/****f* pfsense-utils/gen_requirestatefilter_field
455
 * NAME
456
 *   gen_requirestatefilter_field
457
 * INPUTS
458
 *   Pointer to section object
459
 *   Initial value for the field
460
 * RESULT
461
 *   no return value, section object is updated
462
 ******/
463
function gen_requirestatefilter_field(&$section, $value) {
464
	$section->addInput(new Form_Checkbox(
465
		'requirestatefilter',
466
		'Require State Filter',
467
		'Do not display state table without a filter',
468
		$value
469
	))->setHelp('By default, the entire state table is displayed when entering '.
470
		'Diagnostics > States. This option requires a filter to be entered '.
471
		'before the states are displayed. Useful for systems with large state tables.');
472
}
473
474 f0dc8b68 Phil Davis
/****f* pfsense-utils/gen_created_updated_fields
475
 * NAME
476
 *   gen_created_updated_fields
477
 * INPUTS
478
 *   Pointer to form object
479
 *   Array of created time and username
480
 *   Array of updated time and username
481
 * RESULT
482
 *   no return value, section object is added to form if needed
483
 ******/
484 9c17359f jim-p
function gen_created_updated_fields(&$form, $created, $updated, $tracker = 0) {
485 f0dc8b68 Phil Davis
	$has_created_time = (isset($created['time']) && isset($created['username']));
486
	$has_updated_time = (isset($updated['time']) && isset($updated['username']));
487
488
	if ($has_created_time || $has_updated_time) {
489
		$section = new Form_Section('Rule Information');
490
491 9c17359f jim-p
		if (!empty($tracker)) {
492
			$section->addInput(new Form_StaticText(
493
				'Tracking ID',
494
				htmlspecialchars($tracker)
495
			));
496
		}
497
498 f0dc8b68 Phil Davis
		if ($has_created_time) {
499
			$section->addInput(new Form_StaticText(
500
				'Created',
501 9c17359f jim-p
				htmlspecialchars(sprintf(
502 f0dc8b68 Phil Davis
					gettext('%1$s by %2$s'),
503
					date(gettext("n/j/y H:i:s"), $created['time']),
504 9c17359f jim-p
					$created['username']))
505 f0dc8b68 Phil Davis
			));
506
		}
507
508
		if ($has_updated_time) {
509
			$section->addInput(new Form_StaticText(
510
				'Updated',
511 9c17359f jim-p
				htmlspecialchars(sprintf(
512 f0dc8b68 Phil Davis
					gettext('%1$s by %2$s'),
513
					date(gettext("n/j/y H:i:s"), $updated['time']),
514 9c17359f jim-p
					$updated['username']))
515 f0dc8b68 Phil Davis
			));
516
		}
517
518
		$form->add($section);
519
	}
520
}
521
522 43517fcc Ermal LUÇI
function hardware_offloading_applyflags($iface) {
523
	$flags_on = 0;
524
	$flags_off = 0;
525 3222c70a Reid Linnemann
	$options = get_interface_addresses($iface);
526 43517fcc Ermal LUÇI
527 12a0edbb Viktor G
	/* disable hardware checksum offloading for VirtIO network drivers,
528
	 * see https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=165059 */
529 364c9484 Reid Linnemann
	if (config_path_enabled('system','disablechecksumoffloading') ||
530 d81121e1 Viktor G
	    stristr($iface, "vtnet") || stristr($iface, "ena")) { 
531 23a193da Phil Davis
		if (isset($options['encaps']['txcsum'])) {
532 43517fcc Ermal LUÇI
			$flags_off |= IFCAP_TXCSUM;
533 23a193da Phil Davis
		}
534
		if (isset($options['encaps']['rxcsum'])) {
535 43517fcc Ermal LUÇI
			$flags_off |= IFCAP_RXCSUM;
536 23a193da Phil Davis
		}
537 411d4e6e Luiz Otavio O Souza
		if (isset($options['encaps']['txcsum6'])) {
538
			$flags_off |= IFCAP_TXCSUM_IPV6;
539
		}
540
		if (isset($options['encaps']['rxcsum6'])) {
541
			$flags_off |= IFCAP_RXCSUM_IPV6;
542
		}
543 43517fcc Ermal LUÇI
	} else {
544 bc4d752b jim-p
		if (isset($options['caps']['txcsum'])) {
545 43517fcc Ermal LUÇI
			$flags_on |= IFCAP_TXCSUM;
546 23a193da Phil Davis
		}
547 bc4d752b jim-p
		if (isset($options['caps']['rxcsum'])) {
548 43517fcc Ermal LUÇI
			$flags_on |= IFCAP_RXCSUM;
549 23a193da Phil Davis
		}
550 411d4e6e Luiz Otavio O Souza
		if (isset($options['caps']['txcsum6'])) {
551
			$flags_on |= IFCAP_TXCSUM_IPV6;
552
		}
553
		if (isset($options['caps']['rxcsum6'])) {
554
			$flags_on |= IFCAP_RXCSUM_IPV6;
555
		}
556 43517fcc Ermal LUÇI
	}
557
558 364c9484 Reid Linnemann
	if (config_path_enabled('system','disablesegmentationoffloading')) {
559 43517fcc Ermal LUÇI
		$flags_off |= IFCAP_TSO;
560 cd80be80 Viktor G
		$flags_off |= IFCAP_VLAN_HWTSO;
561 23a193da Phil Davis
	} else if (isset($options['caps']['tso']) || isset($options['caps']['tso4']) || isset($options['caps']['tso6'])) {
562 bc4d752b jim-p
		$flags_on |= IFCAP_TSO;
563 cd80be80 Viktor G
		$flags_on |= IFCAP_VLAN_HWTSO;
564 23a193da Phil Davis
	}
565 43517fcc Ermal LUÇI
566 364c9484 Reid Linnemann
	if (config_path_enabled('system','disablelargereceiveoffloading')) {
567 43517fcc Ermal LUÇI
		$flags_off |= IFCAP_LRO;
568 bc4d752b jim-p
	} else if (isset($options['caps']['lro'])) {
569 43517fcc Ermal LUÇI
		$flags_on |= IFCAP_LRO;
570 23a193da Phil Davis
	}
571 43517fcc Ermal LUÇI
572
	pfSense_interface_capabilities($iface, -$flags_off);
573
	pfSense_interface_capabilities($iface, $flags_on);
574
}
575
576 3076becf Scott Ullrich
/****f* pfsense-utils/enable_hardware_offloading
577
 * NAME
578
 *   enable_hardware_offloading - Enable a NIC's supported hardware features.
579
 * INPUTS
580
 *   $interface	- string containing the physical interface to work on.
581
 * RESULT
582
 *   null
583
 * NOTES
584
 *   This function only supports the fxp driver's loadable microcode.
585
 ******/
586
function enable_hardware_offloading($interface) {
587 a2934331 Scott Ullrich
	$int = get_real_interface($interface);
588 23a193da Phil Davis
	if (empty($int)) {
589 3d063391 Ermal
		return;
590 23a193da Phil Davis
	}
591 43517fcc Ermal LUÇI
592 364c9484 Reid Linnemann
	if (!config_path_enabled('system','do_not_use_nic_microcode')) {
593 43517fcc Ermal LUÇI
		/* translate wan, lan, opt -> real interface if needed */
594
		$int_family = preg_split("/[0-9]+/", $int);
595
		$supported_ints = array('fxp');
596
		if (in_array($int_family, $supported_ints)) {
597 23a193da Phil Davis
			if (does_interface_exist($int)) {
598 43517fcc Ermal LUÇI
				pfSense_interface_flags($int, IFF_LINK0);
599 23a193da Phil Davis
			}
600 43517fcc Ermal LUÇI
		}
601 a2934331 Scott Ullrich
	}
602 3076becf Scott Ullrich
603 43517fcc Ermal LUÇI
	/* This is mostly for vlans and ppp types */
604
	$realhwif = get_parent_interface($interface);
605 23a193da Phil Davis
	if ($realhwif[0] == $int) {
606 43517fcc Ermal LUÇI
		hardware_offloading_applyflags($int);
607 23a193da Phil Davis
	} else {
608 43517fcc Ermal LUÇI
		hardware_offloading_applyflags($realhwif[0]);
609
		hardware_offloading_applyflags($int);
610
	}
611 3076becf Scott Ullrich
}
612
613
/****f* pfsense-utils/is_alias_inuse
614
 * NAME
615
 *   checks to see if an alias is currently in use by a rule
616
 * INPUTS
617
 *
618
 * RESULT
619
 *   true or false
620
 * NOTES
621
 *
622
 ******/
623
function is_alias_inuse($alias) {
624 23a193da Phil Davis
	if ($alias == "") {
625
		return false;
626
	}
627 3076becf Scott Ullrich
	/* loop through firewall rules looking for alias in use */
628 364c9484 Reid Linnemann
	foreach (config_get_path('filter/rule', []) as $rule) {
629
		foreach (['source', 'destination'] as $origin) {
630
			if (array_get_path($rule, "{$origin}/address") == $alias) {
631
				return true;
632 23a193da Phil Davis
			}
633 0c8c496e Scott Ullrich
		}
634 23a193da Phil Davis
	}
635 3076becf Scott Ullrich
	/* loop through nat rules looking for alias in use */
636 364c9484 Reid Linnemann
	foreach (config_get_path('nat/rule', []) as $rule) {
637
		foreach (['target', 'source/address', 'destination/address'] as $property) {
638
			if (array_get_path($rule, $property) == $alias) {
639 3076becf Scott Ullrich
				return true;
640 23a193da Phil Davis
			}
641 3076becf Scott Ullrich
		}
642 23a193da Phil Davis
	}
643 3076becf Scott Ullrich
	return false;
644
}
645
646 63724b02 Scott Dale
/****f* pfsense-utils/is_schedule_inuse
647
 * NAME
648
 *   checks to see if a schedule is currently in use by a rule
649
 * INPUTS
650
 *
651
 * RESULT
652
 *   true or false
653
 * NOTES
654
 *
655
 ******/
656
function is_schedule_inuse($schedule) {
657 23a193da Phil Davis
	if ($schedule == "") {
658
		return false;
659
	}
660 63724b02 Scott Dale
	/* loop through firewall rules looking for schedule in use */
661 364c9484 Reid Linnemann
	foreach (config_get_path('filter/rule', []) as $rule) {
662
		if ($rule['sched'] == $schedule) {
663
			return true;
664 63724b02 Scott Dale
		}
665 23a193da Phil Davis
	}
666 63724b02 Scott Dale
	return false;
667
}
668
669 3076becf Scott Ullrich
/****f* pfsense-utils/setup_microcode
670
 * NAME
671
 *   enumerates all interfaces and calls enable_hardware_offloading which
672
 *   enables a NIC's supported hardware features.
673
 * INPUTS
674
 *
675
 * RESULT
676
 *   null
677
 * NOTES
678
 *   This function only supports the fxp driver's loadable microcode.
679
 ******/
680
function setup_microcode() {
681
682 3a4ce87d Ermal Luçi
	/* if list */
683 80fe8369 Phil Davis
	$iflist = get_configured_interface_list(true);
684 c239afac Reid Linnemann
	foreach (array_keys($iflist) as $if) {
685 3076becf Scott Ullrich
		enable_hardware_offloading($if);
686 23a193da Phil Davis
	}
687 dced0dd0 Ermal LUÇI
	unset($iflist);
688 3076becf Scott Ullrich
}
689
690
/****f* pfsense-utils/get_carp_status
691
 * NAME
692
 *   get_carp_status - Return whether CARP is enabled or disabled.
693
 * RESULT
694
 *   boolean	- true if CARP is enabled, false if otherwise.
695
 ******/
696
function get_carp_status() {
697 5fa78adc Renato Botelho
	/* grab the current status of carp */
698 971de1f9 Renato Botelho
	$status = get_single_sysctl('net.inet.carp.allow');
699 5fa78adc Renato Botelho
	return (intval($status) > 0);
700 3076becf Scott Ullrich
}
701
702 62fb07c8 Reid Linnemann
/**
703
 * Enable or disable CARP by toggling net.inet.carp.allow if necessary, enabling
704
 * only if CARP VIPs are configured
705
 */
706
function enable_carp(bool $enable=true) {
707
	$carp_enabled = get_carp_status();
708
	$carplist = get_configured_vip_list('all', VIP_CARP);
709
	if (($enable != $carp_enabled) && (!$enable || count($carplist) > 0)) {
710
		set_single_sysctl("net.inet.carp.allow", $enable?"1":"0");
711
	}
712
}
713
	
714 3076becf Scott Ullrich
/*
715
 * convert_ip_to_network_format($ip, $subnet): converts an ip address to network form
716
 */
717
function convert_ip_to_network_format($ip, $subnet) {
718 2ce660ad smos
	$ipsplit = explode('.', $ip);
719 3076becf Scott Ullrich
	$string = $ipsplit[0] . "." . $ipsplit[1] . "." . $ipsplit[2] . ".0/" . $subnet;
720
	return $string;
721
}
722
723
/*
724 2a0aef55 Luiz Otavio O Souza
 * get_carp_interface_status($carpid): returns the status of a carp uniqid
725 3076becf Scott Ullrich
 */
726 2a0aef55 Luiz Otavio O Souza
function get_carp_interface_status($carpid) {
727
728
	$carpiface = get_configured_vip_interface($carpid);
729
	if ($carpiface == NULL)
730
		return "";
731
	$interface = get_real_interface($carpiface);
732
	if ($interface == NULL)
733
		return "";
734 5116a8aa Fredrik Rönnvall
	$vip = get_configured_vip($carpid);
735
	if ($vip == NULL || !isset($vip['vhid']))
736
		return "";
737 2a0aef55 Luiz Otavio O Souza
738 5116a8aa Fredrik Rönnvall
	$vhid = $vip['vhid'];
739 c239afac Reid Linnemann
	$carp_query = [];
740
	exec("/sbin/ifconfig {$interface} | /usr/bin/grep \"carp:.* vhid {$vhid} \"", $carp_query);
741 2a0aef55 Luiz Otavio O Souza
	foreach ($carp_query as $int) {
742
		if (stripos($int, "MASTER"))
743
			return "MASTER";
744
		elseif (stripos($int, "BACKUP"))
745
			return "BACKUP";
746
		elseif (stripos($int, "INIT"))
747
			return "INIT";
748 3076becf Scott Ullrich
	}
749 e686a73f Luiz Otavio O Souza
750 0f98065b Luiz Otavio O Souza
	return "";
751 3076becf Scott Ullrich
}
752
753 6ae26227 Viktor G
function get_carp_bind_status($interface) {
754
	$carpstatus = get_carp_interface_status($interface);
755
	if (!empty($carpstatus)) {
756
		return $carpstatus;
757
	} else {
758 364c9484 Reid Linnemann
		foreach (config_get_path('virtualip/vip', []) as $vip) {
759 6ae26227 Viktor G
			if ($interface == "_vip{$vip['uniqid']}") { 
760
				return get_carp_interface_status($vip['interface']);
761
			}
762
		}
763
	}
764
}
765
766 13164061 Augustin-FL
/*
767
 * Return true if the CARP status of at least one interface of a captive portal zone is in backup mode
768
 * This function return false if CARP is not enabled on any interface of the captive portal zone
769
 */
770
function captiveportal_ha_is_node_in_backup_mode($cpzone) {
771 364c9484 Reid Linnemann
	$cpinterfaces = explode(",", config_get_path("captiveportal/{$cpzone}/interface", ""));
772 13164061 Augustin-FL
773 364c9484 Reid Linnemann
	foreach ($cpinterfaces as $interface) {
774
		foreach (config_get_path('virtualip/vip', []) as $vip) {
775
			if (($vip['interface'] == $interface) && ($vip['mode'] == "carp")) {
776
				if (get_carp_interface_status("_vip{$vip['uniqid']}") != "MASTER") {
777
					return true;
778 13164061 Augustin-FL
				}
779
			}
780
		}
781
	}
782
	return false;
783
}
784
785 3076becf Scott Ullrich
/****f* pfsense-utils/WakeOnLan
786
 * NAME
787
 *   WakeOnLan - Wake a machine up using the wake on lan format/protocol
788
 * RESULT
789
 *   true/false - true if the operation was successful
790
 ******/
791 086cf944 Phil Davis
function WakeOnLan($addr, $mac) {
792 3076becf Scott Ullrich
	$addr_byte = explode(':', $mac);
793
	$hw_addr = '';
794
795 4de8f7ba Phil Davis
	for ($a = 0; $a < 6; $a++) {
796 3076becf Scott Ullrich
		$hw_addr .= chr(hexdec($addr_byte[$a]));
797 23a193da Phil Davis
	}
798 3076becf Scott Ullrich
799
	$msg = chr(255).chr(255).chr(255).chr(255).chr(255).chr(255);
800
801 23a193da Phil Davis
	for ($a = 1; $a <= 16; $a++) {
802 3076becf Scott Ullrich
		$msg .= $hw_addr;
803 23a193da Phil Davis
	}
804 3076becf Scott Ullrich
805
	// send it to the broadcast address using UDP
806
	$s = socket_create(AF_INET, SOCK_DGRAM, SOL_UDP);
807
	if ($s == false) {
808 7d1b238c Carlos Eduardo Ramos
		log_error(gettext("Error creating socket!"));
809 c239afac Reid Linnemann
		log_error(sprintf(gettext("Error code is '%1\$s' - %2\$s"), socket_last_error(), socket_strerror(socket_last_error())));
810 3076becf Scott Ullrich
	} else {
811
		// setting a broadcast option to socket:
812 4de8f7ba Phil Davis
		$opt_ret = socket_set_option($s, 1, 6, TRUE);
813 23a193da Phil Davis
		if ($opt_ret < 0) {
814 c239afac Reid Linnemann
			log_error(sprintf(gettext("setsockopt() failed, error: %s"),
815
							  socket_strerror(socket_last_error($s))));
816 23a193da Phil Davis
		}
817 3076becf Scott Ullrich
		$e = socket_sendto($s, $msg, strlen($msg), 0, $addr, 2050);
818
		socket_close($s);
819 e8c516a0 Phil Davis
		log_error(sprintf(gettext('Magic Packet sent (%1$s) to (%2$s) MAC=%3$s'), $e, $addr, $mac));
820 3076becf Scott Ullrich
		return true;
821 0c8c496e Scott Ullrich
	}
822 3076becf Scott Ullrich
823
	return false;
824
}
825
826
/*
827
 * reverse_strrchr($haystack, $needle):  Return everything in $haystack up to the *last* instance of $needle.
828
 *					 Useful for finding paths and stripping file extensions.
829
 */
830
function reverse_strrchr($haystack, $needle) {
831 23a193da Phil Davis
	if (!is_string($haystack)) {
832 4824d857 Ermal Lu?i
		return;
833 23a193da Phil Davis
	}
834
	return strrpos($haystack, $needle) ? substr($haystack, 0, strrpos($haystack, $needle) +1) : false;
835 3076becf Scott Ullrich
}
836
837
/*
838
 *  backup_config_section($section): returns as an xml file string of
839
 *                                   the configuration section
840
 */
841 8dcca9b5 Darren Embry
function backup_config_section($section_name) {
842 364c9484 Reid Linnemann
	$new_section = config_get_path($section_name, []);
843 3076becf Scott Ullrich
	/* generate configuration XML */
844 8dcca9b5 Darren Embry
	$xmlconfig = dump_xml_config($new_section, $section_name);
845 3076becf Scott Ullrich
	$xmlconfig = str_replace("<?xml version=\"1.0\"?>", "", $xmlconfig);
846
	return $xmlconfig;
847
}
848
849
/*
850 8dcca9b5 Darren Embry
 *  restore_config_section($section_name, new_contents): restore a configuration section,
851 3076becf Scott Ullrich
 *                                                  and write the configuration out
852
 *                                                  to disk/cf.
853
 */
854 8dcca9b5 Darren Embry
function restore_config_section($section_name, $new_contents) {
855 364c9484 Reid Linnemann
	global $g;
856 4de8f7ba Phil Davis
	$fout = fopen("{$g['tmp_path']}/tmpxml", "w");
857 3076becf Scott Ullrich
	fwrite($fout, $new_contents);
858
	fclose($fout);
859 8dcca9b5 Darren Embry
860 2568e151 Christian McDonald
	$xml = parse_xml_config(g_get('tmp_path') . "/tmpxml", null);
861 8dcca9b5 Darren Embry
	if ($xml['pfsense']) {
862
		$xml = $xml['pfsense'];
863
	}
864
	if ($xml[$section_name]) {
865
		$section_xml = $xml[$section_name];
866
	} else {
867
		$section_xml = -1;
868
	}
869
870 2568e151 Christian McDonald
	@unlink(g_get('tmp_path') . "/tmpxml");
871 8dcca9b5 Darren Embry
	if ($section_xml === -1) {
872
		return false;
873
	}
874 0430b1b4 Renato Botelho
875
	/* Save current pkg repo to re-add on new config */
876
	unset($pkg_repo_conf_path);
877
	if ($section_name == "system" &&
878 364c9484 Reid Linnemann
	    config_get_path('system/pkg_repo_conf_path')) {
879
		$pkg_repo_conf_path = config_get_path('system/pkg_repo_conf_path');
880 0430b1b4 Renato Botelho
	}
881
882 364c9484 Reid Linnemann
	config_set_path($section_name, $section_xml);
883 23a193da Phil Davis
	if (file_exists("{$g['tmp_path']}/config.cache")) {
884 a57d6170 Scott Ullrich
		unlink("{$g['tmp_path']}/config.cache");
885 23a193da Phil Davis
	}
886 0430b1b4 Renato Botelho
887
	/* Restore previously pkg repo configured */
888
	if ($section_name == "system") {
889
		if (isset($pkg_repo_conf_path)) {
890 364c9484 Reid Linnemann
			config_set_path('system/pkg_repo_conf_path', $pkg_repo_conf_path);
891
		} elseif (config_get_path('system/pkg_repo_conf_path')) {
892
			config_del_path(('system/pkg_repo_conf_path'));
893 0430b1b4 Renato Botelho
		}
894
	}
895
896 8dcca9b5 Darren Embry
	write_config(sprintf(gettext("Restored %s of config file (maybe from CARP partner)"), $section_name));
897 0f806eca Erik Fonnesbeck
	disable_security_checks();
898 8dcca9b5 Darren Embry
	return true;
899 3076becf Scott Ullrich
}
900
901
/*
902 8dcca9b5 Darren Embry
 *  merge_config_section($section_name, new_contents):   restore a configuration section,
903 3076becf Scott Ullrich
 *                                                  and write the configuration out
904
 *                                                  to disk/cf.  But preserve the prior
905
 * 													structure if needed
906
 */
907 8dcca9b5 Darren Embry
function merge_config_section($section_name, $new_contents) {
908 c239afac Reid Linnemann
	$fname = get_tmp_file();
909 3076becf Scott Ullrich
	$fout = fopen($fname, "w");
910
	fwrite($fout, $new_contents);
911
	fclose($fout);
912 8dcca9b5 Darren Embry
	$section_xml = parse_xml_config($fname, $section_name);
913 364c9484 Reid Linnemann
	config_set_path($section_name, $section_xml);
914 3076becf Scott Ullrich
	unlink($fname);
915 8dcca9b5 Darren Embry
	write_config(sprintf(gettext("Restored %s of config file (maybe from CARP partner)"), $section_name));
916 0f806eca Erik Fonnesbeck
	disable_security_checks();
917 3076becf Scott Ullrich
	return;
918
}
919
920
/*
921 4de8f7ba Phil Davis
 * rmdir_recursive($path, $follow_links=false)
922 3076becf Scott Ullrich
 * Recursively remove a directory tree (rm -rf path)
923
 * This is for directories _only_
924
 */
925 4de8f7ba Phil Davis
function rmdir_recursive($path, $follow_links=false) {
926 3076becf Scott Ullrich
	$to_do = glob($path);
927 23a193da Phil Davis
	if (!is_array($to_do)) {
928
		$to_do = array($to_do);
929
	}
930
	foreach ($to_do as $workingdir) { // Handle wildcards by foreaching.
931
		if (file_exists($workingdir)) {
932
			if (is_dir($workingdir)) {
933 3076becf Scott Ullrich
				$dir = opendir($workingdir);
934
				while ($entry = readdir($dir)) {
935 23a193da Phil Davis
					if (is_file("$workingdir/$entry") || ((!$follow_links) && is_link("$workingdir/$entry"))) {
936 3076becf Scott Ullrich
						unlink("$workingdir/$entry");
937 4de8f7ba Phil Davis
					} elseif (is_dir("$workingdir/$entry") && $entry != '.' && $entry != '..') {
938 3076becf Scott Ullrich
						rmdir_recursive("$workingdir/$entry");
939 23a193da Phil Davis
					}
940 6613a031 Scott Ullrich
				}
941 3076becf Scott Ullrich
				closedir($dir);
942
				rmdir($workingdir);
943
			} elseif (is_file($workingdir)) {
944
				unlink($workingdir);
945
			}
946 5fa78adc Renato Botelho
		}
947 3076becf Scott Ullrich
	}
948
	return;
949
}
950
951 e501de37 Ermal
/*
952
 * host_firmware_version(): Return the versions used in this install
953
 */
954 c239afac Reid Linnemann
function host_firmware_version() {
955 364c9484 Reid Linnemann
	global $g;
956 e501de37 Ermal
957 02406801 jim-p
	$os_version = trim(substr(php_uname("r"), 0, strpos(php_uname("r"), '-')));
958
959 5fa78adc Renato Botelho
	return array(
960 2568e151 Christian McDonald
		"firmware" => array("version" => g_get('product_version')),
961 02406801 jim-p
		"kernel"   => array("version" => $os_version),
962
		"base"     => array("version" => $os_version),
963 2568e151 Christian McDonald
		"platform" => g_get('product_label'),
964 364c9484 Reid Linnemann
		"config_version" => config_get_path('version')
965 5fa78adc Renato Botelho
	);
966 e501de37 Ermal
}
967
968 3076becf Scott Ullrich
function get_disk_info() {
969
	$diskout = "";
970
	exec("/bin/df -h | /usr/bin/grep -w '/' | /usr/bin/awk '{ print $2, $3, $4, $5 }'", $diskout);
971
	return explode(' ', $diskout[0]);
972
}
973
974
/****f* pfsense-utils/strncpy
975
 * NAME
976
 *   strncpy - copy strings
977
 * INPUTS
978
 *   &$dst, $src, $length
979
 * RESULT
980
 *   none
981
 ******/
982
function strncpy(&$dst, $src, $length) {
983
	if (strlen($src) > $length) {
984
		$dst = substr($src, 0, $length);
985
	} else {
986
		$dst = $src;
987
	}
988
}
989
990
/****f* pfsense-utils/reload_interfaces_sync
991
 * NAME
992
 *   reload_interfaces - reload all interfaces
993
 * INPUTS
994
 *   none
995
 * RESULT
996
 *   none
997
 ******/
998
function reload_interfaces_sync() {
999 c0836064 Ermal Luçi
	global $config, $g;
1000 3076becf Scott Ullrich
1001 2568e151 Christian McDonald
	if (g_get('debug')) {
1002 7d1b238c Carlos Eduardo Ramos
		log_error(gettext("reload_interfaces_sync() is starting."));
1003 23a193da Phil Davis
	}
1004 3076becf Scott Ullrich
1005
	/* parse config.xml again */
1006
	$config = parse_config(true);
1007
1008 a5d6f60b Ermal Lu?i
	/* enable routing */
1009
	system_routing_enable();
1010 2568e151 Christian McDonald
	if (g_get('debug')) {
1011 7d1b238c Carlos Eduardo Ramos
		log_error(gettext("Enabling system routing"));
1012 23a193da Phil Davis
	}
1013 3076becf Scott Ullrich
1014 2568e151 Christian McDonald
	if (g_get('debug')) {
1015 7d1b238c Carlos Eduardo Ramos
		log_error(gettext("Cleaning up Interfaces"));
1016 23a193da Phil Davis
	}
1017 3076becf Scott Ullrich
1018 67ee1ec5 Ermal Luçi
	/* set up interfaces */
1019
	interfaces_configure();
1020 3076becf Scott Ullrich
}
1021
1022
/****f* pfsense-utils/reload_all
1023
 * NAME
1024
 *   reload_all - triggers a reload of all settings
1025
 *   * INPUTS
1026
 *   none
1027
 * RESULT
1028
 *   none
1029
 ******/
1030
function reload_all() {
1031 0ae6daf8 Ermal
	send_event("service reload all");
1032 3076becf Scott Ullrich
}
1033
1034
/****f* pfsense-utils/reload_interfaces
1035
 * NAME
1036
 *   reload_interfaces - triggers a reload of all interfaces
1037
 * INPUTS
1038
 *   none
1039
 * RESULT
1040
 *   none
1041
 ******/
1042
function reload_interfaces() {
1043 5e3a84e2 Ermal
	send_event("interface all reload");
1044 3076becf Scott Ullrich
}
1045
1046
/****f* pfsense-utils/reload_all_sync
1047
 * NAME
1048
 *   reload_all - reload all settings
1049
 *   * INPUTS
1050
 *   none
1051
 * RESULT
1052
 *   none
1053
 ******/
1054
function reload_all_sync() {
1055 c239afac Reid Linnemann
	global $config;
1056 3076becf Scott Ullrich
1057
	/* parse config.xml again */
1058
	$config = parse_config(true);
1059
1060
	/* set up our timezone */
1061
	system_timezone_configure();
1062
1063
	/* set up our hostname */
1064
	system_hostname_configure();
1065
1066
	/* make hosts file */
1067
	system_hosts_generate();
1068
1069
	/* generate resolv.conf */
1070
	system_resolvconf_generate();
1071
1072
	/* enable routing */
1073
	system_routing_enable();
1074
1075 a5d6f60b Ermal Lu?i
	/* set up interfaces */
1076
	interfaces_configure();
1077 3076becf Scott Ullrich
1078
	/* start dyndns service */
1079
	services_dyndns_configure();
1080
1081
	/* configure cron service */
1082
	configure_cron();
1083
1084
	/* start the NTP client */
1085
	system_ntp_configure();
1086
1087
	/* sync pw database */
1088 6b0c5879 Scott Ullrich
	unlink_if_exists("/etc/spwd.db.tmp");
1089 3076becf Scott Ullrich
	mwexec("/usr/sbin/pwd_mkdb -d /etc/ /etc/master.passwd");
1090
1091
	/* restart sshd */
1092 0ae6daf8 Ermal
	send_event("service restart sshd");
1093 3076becf Scott Ullrich
1094
	/* restart webConfigurator if needed */
1095 0ae6daf8 Ermal
	send_event("service restart webgui");
1096 3076becf Scott Ullrich
}
1097
1098 7f943a22 jim-p
function load_loader_conf($loader_conf = NULL, $local = false) {
1099 d0af08f5 Luiz Souza
1100
	if ($loader_conf == NULL) {
1101
		return (NULL);
1102
	}
1103
	if (file_exists($loader_conf)) {
1104 56b72761 Luiz Souza
		$input = file_get_contents($loader_conf);
1105 d0af08f5 Luiz Souza
	} else {
1106
		$input = "";
1107
	}
1108
1109
	$input_split = explode("\n", $input);
1110
1111
	/*
1112
	 * Loop through and only add lines that are not empty and not
1113
	 * managed by us.
1114
	 */
1115
	$data = array();
1116 7f943a22 jim-p
	/* These values should be removed from loader.conf and loader.conf.local
1117
	 * As they will be replaced when necessary. */
1118 2984a4b1 Luiz Otavio O Souza
	$remove = array(
1119
	    "hint.cordbuc.0",
1120
	    "hint.e6000sw.0",
1121
	    "hint.gpioled",
1122
	    "hint.mdio.0.at",
1123
	    "hint-model.",
1124
	    "hw.e6000sw.default_disabled",
1125
	    "hw.hn.vf_transparent",
1126
	    "hw.hn.use_if_start",
1127
	    "hw.usb.no_pf",
1128
	    "net.pf.request_maxcount",
1129
	    "vm.pmap.pti",
1130
	);
1131 7f943a22 jim-p
	if (!$local) {
1132
		/* These values should only be filtered in loader.conf, not .local */
1133 2984a4b1 Luiz Otavio O Souza
		$remove = array_merge($remove, array(
1134
		    "autoboot_delay",
1135
		    "boot_multicons",
1136
		    "boot_serial",
1137
		    "comconsole_speed",
1138
		    "comconsole_port",
1139
		    "console",
1140
		    "debug.ddb.capture.bufsize",
1141
		    "hint.uart.0.flags",
1142
		    "hint.uart.1.flags",
1143
		    "net.link.ifqmaxlen"
1144
		));
1145 7f943a22 jim-p
	}
1146 d0af08f5 Luiz Souza
	foreach ($input_split as $line) {
1147 40a530a1 Luiz Souza
		if (empty($line)) {
1148
			continue;
1149 d0af08f5 Luiz Souza
		}
1150 21bacf01 Luiz Souza
		$skip = false;
1151 c239afac Reid Linnemann
		$name = explode('=', $line, 2)[0];
1152
		foreach($remove as $rkey) {
1153 0285d8e5 Luiz Souza
			if (strncasecmp(trim($name), $rkey, strlen($rkey)) == 0) {
1154 21bacf01 Luiz Souza
				$skip = true;
1155
				break;
1156
			}
1157
		}
1158
		if (!$skip) {
1159 130fe575 Luiz Souza
			$data[] = $line;
1160
		}
1161 d0af08f5 Luiz Souza
	}
1162 ab105bf8 Luiz Souza
1163
	return ($data);
1164 d0af08f5 Luiz Souza
}
1165
1166 26a38669 Luiz Souza
function setup_loader_settings($path = "", $upgrade = false) {
1167 364c9484 Reid Linnemann
	global $g;
1168 26a38669 Luiz Souza
1169 196d0085 jim-p
	$boot_config_file = "{$path}/boot.config";
1170
	$loader_conf_file = "{$path}/boot/loader.conf";
1171 3076becf Scott Ullrich
1172 364c9484 Reid Linnemann
	$serialspeed = (config_get_path('system/serialspeed', 115200));
1173 986e77a2 Renato Botelho
1174 26a38669 Luiz Souza
	$vga_only = false;
1175
	$serial_only = false;
1176 dc61252a Renato Botelho
	$specific_platform = system_identify_specific_platform();
1177 2f73f2f9 jim-p
	$video_console_type = (get_single_sysctl("machdep.bootmethod") == "UEFI") ? "efi" : "vidconsole";
1178 231fc598 Luiz Otavio O Souza
	if ($specific_platform['name'] == '1540' ||
1179
	    $specific_platform['name'] == '1541') {
1180 c7300778 Renato Botelho
		$vga_only = true;
1181 7ae13d1f Luiz Souza
	} elseif ($specific_platform['name'] == 'Turbot Dual-E') {
1182 5e5df38f jim-p
		$g['primaryconsole_force'] = "video";
1183 c7300778 Renato Botelho
	} elseif ($specific_platform['name'] == 'RCC-VE' ||
1184 dc61252a Renato Botelho
	    $specific_platform['name'] == 'RCC' ||
1185 0a031fc7 Renato Botelho
	    $specific_platform['name'] == 'SG-2220' ||
1186 089c18f3 Brett Keller
	    $specific_platform['name'] == 'apu2') {
1187 60f164f3 Renato Botelho
		$serial_only = true;
1188
	}
1189 986e77a2 Renato Botelho
1190 26a38669 Luiz Souza
	/* Serial console - write out /boot.config */
1191
	if (file_exists($boot_config_file)) {
1192
		$boot_config = file_get_contents($boot_config_file);
1193
	} else {
1194
		$boot_config = "";
1195
	}
1196 60f164f3 Renato Botelho
	$boot_config_split = explode("\n", $boot_config);
1197 6172f3de Renato Botelho
	$data = array();
1198
	foreach ($boot_config_split as $bcs) {
1199 231fc598 Luiz Otavio O Souza
		/* Ignore -S, -D and -h lines now */
1200
		if (!empty($bcs) && !strstr($bcs, "-S") &&
1201
		    !strstr($bcs, "-D") && !strstr($bcs, "-h")) {
1202 6172f3de Renato Botelho
			$data[] = $bcs;
1203 0c8c496e Scott Ullrich
		}
1204 6172f3de Renato Botelho
	}
1205
	if ($serial_only === true) {
1206
		$data[] = "-S{$serialspeed} -h";
1207
	} elseif (is_serial_enabled()) {
1208
		$data[] = "-S{$serialspeed} -D";
1209 60f164f3 Renato Botelho
	}
1210 5f36c658 jim-p
1211 6172f3de Renato Botelho
	if (empty($data)) {
1212 c239afac Reid Linnemann
		@unlink($boot_config_file);
1213 6172f3de Renato Botelho
	} else {
1214
		safe_write_file($boot_config_file, $data);
1215
	}
1216 26a38669 Luiz Souza
	unset($data, $boot_config, $boot_config_file, $boot_config_split);
1217 6172f3de Renato Botelho
1218 26a38669 Luiz Souza
	/* Serial console - write out /boot/loader.conf */
1219
	if ($upgrade) {
1220 60f164f3 Renato Botelho
		system("echo \"Reading {$loader_conf_file}...\" >> /conf/upgrade_log.txt");
1221
	}
1222 25c088de Renato Botelho
1223 1ef4cbdb Luiz Souza
	$data = load_loader_conf($loader_conf_file, false);
1224 6172f3de Renato Botelho
	if ($serial_only === true) {
1225
		$data[] = 'boot_serial="YES"';
1226
		$data[] = 'console="comconsole"';
1227 d0af08f5 Luiz Souza
		$data[] = 'comconsole_speed="' . $serialspeed . '"';
1228 c7300778 Renato Botelho
	} elseif ($vga_only === true) {
1229 b51ea481 jim-p
		if ($video_console_type == 'efi') {
1230
			$data[] = 'boot_serial="NO"';
1231
		}
1232 2f73f2f9 jim-p
		$data[] = "console=\"{$video_console_type}\"";
1233 c7300778 Renato Botelho
	} elseif (is_serial_enabled()) {
1234 6172f3de Renato Botelho
		$data[] = 'boot_multicons="YES"';
1235
		$primaryconsole = isset($g['primaryconsole_force']) ?
1236 2568e151 Christian McDonald
		    g_get('primaryconsole_force') :
1237 364c9484 Reid Linnemann
		    config_get_path('system/primaryconsole');
1238 6172f3de Renato Botelho
		switch ($primaryconsole) {
1239
			case "video":
1240 b51ea481 jim-p
				if ($video_console_type == 'efi') {
1241
					$data[] = 'boot_serial="NO"';
1242
				}
1243 2f73f2f9 jim-p
				$data[] = "console=\"{$video_console_type},comconsole\"";
1244 6172f3de Renato Botelho
				break;
1245
			case "serial":
1246
			default:
1247 067f3650 jim-p
				$data[] = 'boot_serial="YES"';
1248 2f73f2f9 jim-p
				$data[] = "console=\"comconsole,{$video_console_type}\"";
1249 6172f3de Renato Botelho
		}
1250 d0af08f5 Luiz Souza
		$data[] = 'comconsole_speed="' . $serialspeed . '"';
1251 b51ea481 jim-p
	} elseif ($video_console_type == 'efi') {
1252
		$data[] = 'boot_serial="NO"';
1253 0c8c496e Scott Ullrich
	}
1254 6172f3de Renato Botelho
1255 c7300778 Renato Botelho
	if ($specific_platform['name'] == 'RCC-VE' ||
1256
	    $specific_platform['name'] == 'RCC' ||
1257 0a031fc7 Renato Botelho
	    $specific_platform['name'] == 'SG-2220') {
1258 6172f3de Renato Botelho
		$data[] = 'comconsole_port="0x2F8"';
1259
		$data[] = 'hint.uart.0.flags="0x00"';
1260
		$data[] = 'hint.uart.1.flags="0x10"';
1261
	}
1262 d0af08f5 Luiz Souza
	$data[] = 'autoboot_delay="3"';
1263 364c9484 Reid Linnemann
	if (config_path_enabled('system','pti_disabled')) {
1264 26a38669 Luiz Souza
		$data[] = 'vm.pmap.pti="0"';
1265
	}
1266 6172f3de Renato Botelho
1267 2360abcc Luiz Souza
	/* Enable ALTQ support for hnX NICs. */
1268 364c9484 Reid Linnemann
	if (config_path_enabled('system','hn_altq_enable')) {
1269 b6d6cd61 Luiz Souza
		$data[] = 'hw.hn.vf_transparent="0"';
1270
		$data[] = 'hw.hn.use_if_start="1"';
1271
	}
1272 2360abcc Luiz Souza
1273 ae241eea Kristof Provost
	/* Set maximum send queue length. */
1274
	$data[] = 'net.link.ifqmaxlen="128"';
1275
1276 6172f3de Renato Botelho
	safe_write_file($loader_conf_file, $data);
1277
1278 d0af08f5 Luiz Souza
	/* Filter loader.conf.local to avoid duplicate settings. */
1279
	$loader_conf_file = "{$path}/boot/loader.conf.local";
1280 7f943a22 jim-p
	$data = load_loader_conf($loader_conf_file, true);
1281 d0af08f5 Luiz Souza
	if (empty($data)) {
1282
		@unlink($loader_conf_file);
1283
	} else {
1284
		safe_write_file($loader_conf_file, $data);
1285
	}
1286 6172f3de Renato Botelho
1287 26a38669 Luiz Souza
}
1288
1289 749dfdb7 Luiz Souza
function console_configure($when = "save", $path = "") {
1290 26a38669 Luiz Souza
	$ttys_file = "{$path}/etc/ttys";
1291
1292
	/* Update the loader settings. */
1293
	setup_loader_settings($path, ($when == "upgrade"));
1294
1295 02e4ee54 Renato Botelho
	$ttys = file_get_contents($ttys_file);
1296 cfbfd941 smos
	$ttys_split = explode("\n", $ttys);
1297 6172f3de Renato Botelho
1298
	$data = array();
1299 c5f9fb72 Renato Botelho
1300 4f009171 Renato Botelho
	$on_off = (is_serial_enabled() ? 'onifconsole' : 'off');
1301 c5f9fb72 Renato Botelho
1302 364c9484 Reid Linnemann
	if (config_path_enabled('system','disableconsolemenu')) {
1303 edb4b657 Renato Botelho
		$console_type = 'Pc';
1304 3f38f937 Luiz Otavio O Souza
		$serial_type = '3wire';
1305 edb4b657 Renato Botelho
	} else {
1306
		$console_type = 'al.Pc';
1307 3f38f937 Luiz Otavio O Souza
		$serial_type = 'al.3wire';
1308 edb4b657 Renato Botelho
	}
1309 237d29c4 Renato Botelho
1310 6172f3de Renato Botelho
	$console_line = "console\tnone\t\t\t\tunknown\toff\tsecure";
1311 5e280f4b Viktor G
	$virt_line =
1312
	    "\"/usr/libexec/getty {$console_type}\"\txterm\tonifexists secure";
1313 6172f3de Renato Botelho
	$ttyu_line =
1314
	    "\"/usr/libexec/getty {$serial_type}\"\tvt100\t{$on_off}\tsecure";
1315 237d29c4 Renato Botelho
1316
	$found = array();
1317
1318 23a193da Phil Davis
	foreach ($ttys_split as $tty) {
1319 6172f3de Renato Botelho
		/* Ignore blank lines */
1320
		if (empty($tty)) {
1321
			continue;
1322
		}
1323
1324 23a193da Phil Davis
		if (stristr($tty, "ttyv0")) {
1325 237d29c4 Renato Botelho
			$found['ttyv0'] = 1;
1326 5e280f4b Viktor G
			$data[] = "ttyv0\t{$virt_line}";
1327
		} elseif (stristr($tty, "xc0")) {
1328
			$found['xc0'] = 1;
1329
			$data[] = "xc0\t{$virt_line}";
1330 237d29c4 Renato Botelho
		} elseif (stristr($tty, "ttyu")) {
1331 4f009171 Renato Botelho
			$ttyn = substr($tty, 0, 5);
1332 237d29c4 Renato Botelho
			$found[$ttyn] = 1;
1333 6172f3de Renato Botelho
			$data[] = "{$ttyn}\t{$ttyu_line}";
1334 237d29c4 Renato Botelho
		} elseif (substr($tty, 0, 7) == 'console') {
1335
			$found['console'] = 1;
1336 6172f3de Renato Botelho
			$data[] = $tty;
1337 23a193da Phil Davis
		} else {
1338 6172f3de Renato Botelho
			$data[] = $tty;
1339 23a193da Phil Davis
		}
1340 3076becf Scott Ullrich
	}
1341 edb4b657 Renato Botelho
	unset($on_off, $console_type, $serial_type);
1342 237d29c4 Renato Botelho
1343
	/* Detect missing main lines on original file and try to rebuild it */
1344
	$items = array(
1345
		'console',
1346
		'ttyv0',
1347
		'ttyu0',
1348
		'ttyu1',
1349
		'ttyu2',
1350 5e280f4b Viktor G
		'ttyu3',
1351
		'xc0'
1352 237d29c4 Renato Botelho
	);
1353
1354
	foreach ($items as $item) {
1355
		if (isset($found[$item])) {
1356
			continue;
1357
		}
1358
1359
		if ($item == 'console') {
1360 6172f3de Renato Botelho
			$data[] = $console_line;
1361 5e280f4b Viktor G
		} elseif (($item == 'ttyv0') || ($item == 'xc0')) {
1362
			/* xc0 - Xen console, see https://redmine.pfsense.org/issues/11402 */
1363
			$data[] = "{$item}\t{$virt_line}";
1364 237d29c4 Renato Botelho
		} else {
1365 6172f3de Renato Botelho
			$data[] = "{$item}\t{$ttyu_line}";
1366 237d29c4 Renato Botelho
		}
1367
	}
1368
1369 6172f3de Renato Botelho
	safe_write_file($ttys_file, $data);
1370
1371
	unset($ttys, $ttys_file, $ttys_split, $data);
1372
1373 23a193da Phil Davis
	if ($when != "upgrade") {
1374 02e4ee54 Renato Botelho
		reload_ttys();
1375 23a193da Phil Davis
	}
1376 a46e450c Ermal Lu?i
1377 3076becf Scott Ullrich
	return;
1378
}
1379
1380 38c7d42e Renato Botelho
function is_serial_enabled() {
1381 364c9484 Reid Linnemann
	global $g;
1382 38c7d42e Renato Botelho
1383
	if (!isset($g['enableserial_force']) &&
1384 364c9484 Reid Linnemann
	    !config_path_enabled('system','enableserial')) {
1385 38c7d42e Renato Botelho
		return false;
1386 23a193da Phil Davis
	}
1387 38c7d42e Renato Botelho
1388
	return true;
1389
}
1390
1391 edb4b657 Renato Botelho
function reload_ttys() {
1392
	// Send a HUP signal to init will make it reload /etc/ttys
1393
	posix_kill(1, SIGHUP);
1394
}
1395
1396 3076becf Scott Ullrich
function print_value_list($list, $count = 10, $separator = ",") {
1397 c239afac Reid Linnemann
	$ret = implode($separator, array_slice($list, 0, $count));
1398 23a193da Phil Davis
	if (count($list) < $count) {
1399 c239afac Reid Linnemann
		$ret .= ".";
1400 3076becf Scott Ullrich
	} else {
1401 c239afac Reid Linnemann
		$ret .= "...";
1402 3076becf Scott Ullrich
	}
1403 c239afac Reid Linnemann
	return $ret;
1404 3076becf Scott Ullrich
}
1405
1406 bfe776f0 Ermal Luçi
/* DHCP enabled on any interfaces? */
1407 abdd01f5 Ermal
function is_dhcp_server_enabled() {
1408 364c9484 Reid Linnemann
	foreach (config_get_path('dhcpd', []) as $dhcpif => $dhcpifconf) {
1409 fae6b2c0 jim-p
		if (empty($dhcpifconf)) {
1410
			continue;
1411
		}
1412 364c9484 Reid Linnemann
		if (isset($dhcpifconf['enable']) &&
1413
			!empty(config_get_path("interfaces/{$dhcpif}"))) {
1414 abdd01f5 Ermal
			return true;
1415 23a193da Phil Davis
		}
1416 3076becf Scott Ullrich
	}
1417 bfe776f0 Ermal Luçi
1418 abdd01f5 Ermal
	return false;
1419 a6610d82 smos
}
1420
1421
/* DHCP enabled on any interfaces? */
1422 abdd01f5 Ermal
function is_dhcpv6_server_enabled() {
1423 364c9484 Reid Linnemann
	foreach (config_get_path('interfaces', []) as $ifcfg) {
1424
		if (isset($ifcfg['enable']) && !empty($ifcfg['track6-interface'])) {
1425
			return true;
1426 a6610d82 smos
		}
1427
	}
1428
1429 364c9484 Reid Linnemann
	foreach (config_get_path('dhcpdv6', []) as $dhcpv6if => $dhcpv6ifconf) {
1430 fae6b2c0 jim-p
		if (empty($dhcpv6ifconf)) {
1431
			continue;
1432
		}
1433 364c9484 Reid Linnemann
		if (isset($dhcpv6ifconf['enable']) &&
1434
			!empty(config_get_path("interfaces/{$dhcpv6if}"))) {
1435 abdd01f5 Ermal
			return true;
1436 23a193da Phil Davis
		}
1437 65b1e7d5 Seth Mos
	}
1438
1439 abdd01f5 Ermal
	return false;
1440 3076becf Scott Ullrich
}
1441
1442 0ed8d746 bcyrill
/* radvd enabled on any interfaces? */
1443
function is_radvd_enabled() {
1444 364c9484 Reid Linnemann
	init_config_arr(['dhcpdv6']);
1445
	$dhcpdv6cfg = config_get_path('dhcpdv6', []);
1446 0ed8d746 bcyrill
	$Iflist = get_configured_interface_list();
1447
1448
	/* handle manually configured DHCP6 server settings first */
1449
	foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) {
1450 fae6b2c0 jim-p
		if (empty($dhcpv6ifconf)) {
1451
			continue;
1452
		}
1453 9d87553c jim-p
		if (!config_path_enabled("interfaces/{$dhcpv6if}")) {
1454 0ed8d746 bcyrill
			continue;
1455 23a193da Phil Davis
		}
1456 0ed8d746 bcyrill
1457 23a193da Phil Davis
		if (!isset($dhcpv6ifconf['ramode'])) {
1458 0ed8d746 bcyrill
			$dhcpv6ifconf['ramode'] = $dhcpv6ifconf['mode'];
1459 23a193da Phil Davis
		}
1460 0ed8d746 bcyrill
1461 23a193da Phil Davis
		if ($dhcpv6ifconf['ramode'] == "disabled") {
1462 0ed8d746 bcyrill
			continue;
1463 23a193da Phil Davis
		}
1464 0ed8d746 bcyrill
1465
		$ifcfgipv6 = get_interface_ipv6($dhcpv6if);
1466 23a193da Phil Davis
		if (!is_ipaddrv6($ifcfgipv6)) {
1467 0ed8d746 bcyrill
			continue;
1468 23a193da Phil Davis
		}
1469 0ed8d746 bcyrill
1470
		return true;
1471
	}
1472
1473
	/* handle DHCP-PD prefixes and 6RD dynamic interfaces */
1474 c239afac Reid Linnemann
	foreach (array_keys($Iflist) as $if) {
1475 364c9484 Reid Linnemann
		if (!config_path_enabled("interfaces/{$if}", 'track6-interface')) {
1476 0ed8d746 bcyrill
			continue;
1477 23a193da Phil Davis
		}
1478 364c9484 Reid Linnemann
		if (!config_path_enabled("interfaces/{$if}")) {
1479 0ed8d746 bcyrill
			continue;
1480 23a193da Phil Davis
		}
1481 0ed8d746 bcyrill
1482
		$ifcfgipv6 = get_interface_ipv6($if);
1483 23a193da Phil Davis
		if (!is_ipaddrv6($ifcfgipv6)) {
1484 0ed8d746 bcyrill
			continue;
1485 23a193da Phil Davis
		}
1486 0ed8d746 bcyrill
1487
		$ifcfgsnv6 = get_interface_subnetv6($if);
1488
		$subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6);
1489
1490 23a193da Phil Davis
		if (!is_ipaddrv6($subnetv6)) {
1491 0ed8d746 bcyrill
			continue;
1492 23a193da Phil Davis
		}
1493 0ed8d746 bcyrill
1494
		return true;
1495
	}
1496
1497
	return false;
1498
}
1499
1500 93c2c1e6 jim-p
/* Any PPPoE servers enabled? */
1501
function is_pppoe_server_enabled() {
1502
	$pppoeenable = false;
1503
1504 364c9484 Reid Linnemann
	foreach (config_get_path('pppoes/pppoe', []) as $pppoes) {
1505 23a193da Phil Davis
		if ($pppoes['mode'] == 'server') {
1506 93c2c1e6 jim-p
			$pppoeenable = true;
1507 23a193da Phil Davis
		}
1508
	}
1509 93c2c1e6 jim-p
1510
	return $pppoeenable;
1511
}
1512
1513 cf63f163 stilez
/* Optional arg forces hh:mm:ss without days */
1514
function convert_seconds_to_dhms($sec, $showhoursonly = false) {
1515 0bde6d10 stilez
	if (!is_numericint($sec)) {
1516
		return '-';
1517
	}
1518
	// FIXME: When we move to PHP 7 we can use "intdiv($sec % X, Y)" etc
1519 cf63f163 stilez
	list($d, $h, $m, $s) = array(	(int)($showhoursonly ? 0 : $sec/86400),
1520 70381d48 stilez
					(int)(($showhoursonly ? $sec : $sec % 86400)/3600),
1521 0bde6d10 stilez
					(int)(($sec % 3600)/60),
1522
					$sec % 60
1523
				);
1524
	return ($d > 0 ? $d . 'd ' : '') . sprintf('%02d:%02d:%02d', $h, $m, $s);
1525 9ebe7028 gnhb
}
1526 8eb2f33a Scott Ullrich
1527 63292199 gnhb
/* Compute the total uptime from the ppp uptime log file in the conf directory */
1528
1529 23a193da Phil Davis
function get_ppp_uptime($port) {
1530
	if (file_exists("/conf/{$port}.log")) {
1531 5fa78adc Renato Botelho
		$saved_time = file_get_contents("/conf/{$port}.log");
1532 4de8f7ba Phil Davis
		$uptime_data = explode("\n", $saved_time);
1533
		$sec = 0;
1534 23a193da Phil Davis
		foreach ($uptime_data as $upt) {
1535 cf2a2f82 jim-p
			/* Skip blank lines, trim, and cast to int to ensure type matches.
1536
			 * https://redmine.pfsense.org/issues/14117 */
1537
			if (!empty($upt)) {
1538
				$sec += (int) trim(substr($upt, 1 + strpos($upt, " ")));
1539
			}
1540 5fa78adc Renato Botelho
		}
1541 0bde6d10 stilez
		return convert_seconds_to_dhms($sec);
1542 63292199 gnhb
	} else {
1543 7d1b238c Carlos Eduardo Ramos
		$total_time = gettext("No history data found!");
1544 63292199 gnhb
		return $total_time;
1545
	}
1546
}
1547 8eb2f33a Scott Ullrich
1548 6189988d Scott Dale
//returns interface information
1549
function get_interface_info($ifdescr) {
1550 364c9484 Reid Linnemann
	global $g;
1551 6189988d Scott Dale
1552
	$ifinfo = array();
1553 364c9484 Reid Linnemann
	if (empty(config_get_path("interfaces/{$ifdescr}"))) {
1554 67ee1ec5 Ermal Luçi
		return;
1555 23a193da Phil Davis
	}
1556 364c9484 Reid Linnemann
	$ifinfo['hwif'] = config_get_path("interfaces/{$ifdescr}/if");
1557
	$ifinfo['enable'] = config_path_enabled("interfaces/{$ifdescr}");
1558 cffe41cb Ermal
	$ifinfo['if'] = get_real_interface($ifdescr);
1559 6189988d Scott Dale
1560 cb074893 Ermal Lu?i
	$chkif = $ifinfo['if'];
1561 3222c70a Reid Linnemann
	$ifinfotmp = get_interface_addresses($chkif);
1562 cb074893 Ermal Lu?i
	$ifinfo['status'] = $ifinfotmp['status'];
1563 23a193da Phil Davis
	if (empty($ifinfo['status'])) {
1564 5fa78adc Renato Botelho
		$ifinfo['status'] = "down";
1565 23a193da Phil Davis
	}
1566 cb074893 Ermal Lu?i
	$ifinfo['macaddr'] = $ifinfotmp['macaddr'];
1567 2d2e466c Ermal LUÇI
	$ifinfo['mtu'] = $ifinfotmp['mtu'];
1568 cb074893 Ermal Lu?i
	$ifinfo['ipaddr'] = $ifinfotmp['ipaddr'];
1569
	$ifinfo['subnet'] = $ifinfotmp['subnet'];
1570 58418355 smos
	$ifinfo['linklocal'] = get_interface_linklocal($ifdescr);
1571 15cc0894 Seth Mos
	$ifinfo['ipaddrv6'] = get_interface_ipv6($ifdescr);
1572
	$ifinfo['subnetv6'] = get_interface_subnetv6($ifdescr);
1573 23a193da Phil Davis
	if (isset($ifinfotmp['link0'])) {
1574 cb074893 Ermal Lu?i
		$link0 = "down";
1575 23a193da Phil Davis
	}
1576 cffe41cb Ermal
	$ifinfotmp = pfSense_get_interface_stats($chkif);
1577 5fa78adc Renato Botelho
	// $ifinfo['inpkts'] = $ifinfotmp['inpkts'];
1578
	// $ifinfo['outpkts'] = $ifinfotmp['outpkts'];
1579
	$ifinfo['inerrs'] = $ifinfotmp['inerrs'];
1580
	$ifinfo['outerrs'] = $ifinfotmp['outerrs'];
1581
	$ifinfo['collisions'] = $ifinfotmp['collisions'];
1582 6189988d Scott Dale
1583 01385b0c Scott Ullrich
	/* Use pfctl for non wrapping 64 bit counters */
1584 b5a8483c Seth Mos
	/* Pass */
1585 cb074893 Ermal Lu?i
	exec("/sbin/pfctl -vvsI -i {$chkif}", $pfctlstats);
1586 971eaab5 Seth Mos
	$pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]);
1587
	$pf_out4_pass = preg_split("/ +/", $pfctlstats[5]);
1588 15cc0894 Seth Mos
	$pf_in6_pass = preg_split("/ +/ ", $pfctlstats[7]);
1589
	$pf_out6_pass = preg_split("/ +/", $pfctlstats[9]);
1590 971eaab5 Seth Mos
	$in4_pass = $pf_in4_pass[5];
1591
	$out4_pass = $pf_out4_pass[5];
1592
	$in4_pass_packets = $pf_in4_pass[3];
1593
	$out4_pass_packets = $pf_out4_pass[3];
1594 15cc0894 Seth Mos
	$in6_pass = $pf_in6_pass[5];
1595
	$out6_pass = $pf_out6_pass[5];
1596
	$in6_pass_packets = $pf_in6_pass[3];
1597
	$out6_pass_packets = $pf_out6_pass[3];
1598
	$ifinfo['inbytespass'] = $in4_pass + $in6_pass;
1599
	$ifinfo['outbytespass'] = $out4_pass + $out6_pass;
1600
	$ifinfo['inpktspass'] = $in4_pass_packets + $in6_pass_packets;
1601 4bdfa5dd Phil Davis
	$ifinfo['outpktspass'] = $out4_pass_packets + $out6_pass_packets;
1602 01385b0c Scott Ullrich
1603 971eaab5 Seth Mos
	/* Block */
1604
	$pf_in4_block = preg_split("/ +/", $pfctlstats[4]);
1605
	$pf_out4_block = preg_split("/ +/", $pfctlstats[6]);
1606 15cc0894 Seth Mos
	$pf_in6_block = preg_split("/ +/", $pfctlstats[8]);
1607
	$pf_out6_block = preg_split("/ +/", $pfctlstats[10]);
1608 971eaab5 Seth Mos
	$in4_block = $pf_in4_block[5];
1609
	$out4_block = $pf_out4_block[5];
1610
	$in4_block_packets = $pf_in4_block[3];
1611
	$out4_block_packets = $pf_out4_block[3];
1612 15cc0894 Seth Mos
	$in6_block = $pf_in6_block[5];
1613
	$out6_block = $pf_out6_block[5];
1614
	$in6_block_packets = $pf_in6_block[3];
1615
	$out6_block_packets = $pf_out6_block[3];
1616
	$ifinfo['inbytesblock'] = $in4_block + $in6_block;
1617
	$ifinfo['outbytesblock'] = $out4_block + $out6_block;
1618
	$ifinfo['inpktsblock'] = $in4_block_packets + $in6_block_packets;
1619
	$ifinfo['outpktsblock'] = $out4_block_packets + $out6_block_packets;
1620
1621
	$ifinfo['inbytes'] = $in4_pass + $in6_pass;
1622
	$ifinfo['outbytes'] = $out4_pass + $out6_pass;
1623
	$ifinfo['inpkts'] = $in4_pass_packets + $in6_pass_packets;
1624 4bdfa5dd Phil Davis
	$ifinfo['outpkts'] = $out4_pass_packets + $out6_pass_packets;
1625 5fa78adc Renato Botelho
1626 364c9484 Reid Linnemann
	$link_type = config_get_path("interfaces/{$ifdescr}/ipaddr");
1627 59db783a gnhb
	switch ($link_type) {
1628 23a193da Phil Davis
		/* DHCP? -> see if dhclient is up */
1629
		case "dhcp":
1630
			/* see if dhclient is up */
1631
			if (find_dhclient_process($ifinfo['if']) != 0) {
1632
				$ifinfo['dhcplink'] = "up";
1633
			} else {
1634
				$ifinfo['dhcplink'] = "down";
1635 badbe349 gnhb
			}
1636 23a193da Phil Davis
1637 611ae852 Ermal
			break;
1638 23a193da Phil Davis
		/* PPPoE/PPTP/L2TP interface? -> get status from virtual interface */
1639
		case "pppoe":
1640
		case "pptp":
1641
		case "l2tp":
1642
			if ($ifinfo['status'] == "up" && !isset($link0)) {
1643
				/* get PPPoE link status for dial on demand */
1644
				$ifinfo["{$link_type}link"] = "up";
1645
			} else {
1646
				$ifinfo["{$link_type}link"] = "down";
1647 4adf752c smos
			}
1648 23a193da Phil Davis
1649
			break;
1650
		/* PPP interface? -> get uptime for this session and cumulative uptime from the persistent log file in conf */
1651
		case "ppp":
1652
			if ($ifinfo['status'] == "up") {
1653
				$ifinfo['ppplink'] = "up";
1654
			} else {
1655
				$ifinfo['ppplink'] = "down" ;
1656 4adf752c smos
			}
1657 23a193da Phil Davis
1658
			if (empty($ifinfo['status'])) {
1659
				$ifinfo['status'] = "down";
1660
			}
1661
1662 c239afac Reid Linnemann
			foreach (config_get_path('ppps/ppp', []) as $ppp) {
1663 364c9484 Reid Linnemann
				if (config_get_path("interfaces/{$ifdescr}/if") == $ppp['if']) {
1664
					break;
1665 23a193da Phil Davis
				}
1666
			}
1667
			$dev = $ppp['ports'];
1668 364c9484 Reid Linnemann
			if (config_get_path("interfaces/{$ifdescr}/if") != $ppp['if'] || empty($dev)) {
1669 23a193da Phil Davis
				break;
1670
			}
1671
			if (!file_exists($dev)) {
1672
				$ifinfo['nodevice'] = 1;
1673
				$ifinfo['pppinfo'] = $dev . " " . gettext("device not present! Is the modem attached to the system?");
1674
			}
1675
1676
			$usbmodemoutput = array();
1677 84c82d3d doktornotor
			exec("/usr/sbin/usbconfig", $usbmodemoutput);
1678 23a193da Phil Davis
			$mondev = "{$g['tmp_path']}/3gstats.{$ifdescr}";
1679
			if (file_exists($mondev)) {
1680
				$cellstats = file($mondev);
1681
				/* skip header */
1682
				$a_cellstats = explode(",", $cellstats[1]);
1683
				if (preg_match("/huawei/i", implode("\n", $usbmodemoutput))) {
1684
					$ifinfo['cell_rssi'] = huawei_rssi_to_string($a_cellstats[1]);
1685
					$ifinfo['cell_mode'] = huawei_mode_to_string($a_cellstats[2], $a_cellstats[3]);
1686
					$ifinfo['cell_simstate'] = huawei_simstate_to_string($a_cellstats[10]);
1687
					$ifinfo['cell_service'] = huawei_service_to_string(trim($a_cellstats[11]));
1688
				}
1689
				if (preg_match("/zte/i", implode("\n", $usbmodemoutput))) {
1690
					$ifinfo['cell_rssi'] = zte_rssi_to_string($a_cellstats[1]);
1691
					$ifinfo['cell_mode'] = zte_mode_to_string($a_cellstats[2], $a_cellstats[3]);
1692
					$ifinfo['cell_simstate'] = zte_simstate_to_string($a_cellstats[10]);
1693
					$ifinfo['cell_service'] = zte_service_to_string(trim($a_cellstats[11]));
1694
				}
1695
				$ifinfo['cell_upstream'] = $a_cellstats[4];
1696
				$ifinfo['cell_downstream'] = trim($a_cellstats[5]);
1697
				$ifinfo['cell_sent'] = $a_cellstats[6];
1698
				$ifinfo['cell_received'] = trim($a_cellstats[7]);
1699
				$ifinfo['cell_bwupstream'] = $a_cellstats[8];
1700
				$ifinfo['cell_bwdownstream'] = trim($a_cellstats[9]);
1701
			}
1702
			// Calculate cumulative uptime for PPP link. Useful for connections that have per minute/hour contracts so you don't go over!
1703
			if (isset($ppp['uptime'])) {
1704
				$ifinfo['ppp_uptime_accumulated'] = "(".get_ppp_uptime($ifinfo['if']).")";
1705
			}
1706
			break;
1707
		default:
1708
			break;
1709 6189988d Scott Dale
	}
1710 5fa78adc Renato Botelho
1711 59db783a gnhb
	if (file_exists("{$g['varrun_path']}/{$link_type}_{$ifdescr}.pid")) {
1712
		$sec = trim(`/usr/local/sbin/ppp-uptime.sh {$ifinfo['if']}`);
1713 0bde6d10 stilez
		$ifinfo['ppp_uptime'] = convert_seconds_to_dhms($sec);
1714 59db783a gnhb
	}
1715 5fa78adc Renato Botelho
1716 6189988d Scott Dale
	if ($ifinfo['status'] == "up") {
1717
		/* try to determine media with ifconfig */
1718 c239afac Reid Linnemann
		$ifconfiginfo = [];
1719 fc455333 Viktor G
		exec("/sbin/ifconfig -v " . $ifinfo['if'], $ifconfiginfo);
1720 c239afac Reid Linnemann
		$wifconfiginfo = [];
1721 23a193da Phil Davis
		if (is_interface_wireless($ifdescr)) {
1722 818a6b7d Seth Mos
			exec("/sbin/ifconfig {$ifinfo['if']} list sta", $wifconfiginfo);
1723
			array_shift($wifconfiginfo);
1724
		}
1725 6189988d Scott Dale
		$matches = "";
1726
		foreach ($ifconfiginfo as $ici) {
1727
1728
			/* don't list media/speed for wireless cards, as it always
1729
			   displays 2 Mbps even though clients can connect at 11 Mbps */
1730
			if (preg_match("/media: .*? \((.*?)\)/", $ici, $matches)) {
1731
				$ifinfo['media'] = $matches[1];
1732
			} else if (preg_match("/media: Ethernet (.*)/", $ici, $matches)) {
1733
				$ifinfo['media'] = $matches[1];
1734
			} else if (preg_match("/media: IEEE 802.11 Wireless Ethernet (.*)/", $ici, $matches)) {
1735
				$ifinfo['media'] = $matches[1];
1736
			}
1737
1738
			if (preg_match("/status: (.*)$/", $ici, $matches)) {
1739 23a193da Phil Davis
				if ($matches[1] != "active") {
1740 6189988d Scott Dale
					$ifinfo['status'] = $matches[1];
1741 23a193da Phil Davis
				}
1742
				if ($ifinfo['status'] == gettext("running")) {
1743 7d1b238c Carlos Eduardo Ramos
					$ifinfo['status'] = gettext("up");
1744 23a193da Phil Davis
				}
1745 6189988d Scott Dale
			}
1746
			if (preg_match("/channel (\S*)/", $ici, $matches)) {
1747
				$ifinfo['channel'] = $matches[1];
1748
			}
1749
			if (preg_match("/ssid (\".*?\"|\S*)/", $ici, $matches)) {
1750 23a193da Phil Davis
				if ($matches[1][0] == '"') {
1751 6189988d Scott Dale
					$ifinfo['ssid'] = substr($matches[1], 1, -1);
1752 23a193da Phil Davis
				}
1753
				else {
1754 6189988d Scott Dale
					$ifinfo['ssid'] = $matches[1];
1755 23a193da Phil Davis
				}
1756 6189988d Scott Dale
			}
1757 0b29093b jim-p
			if (preg_match("/laggproto (.*)$/", $ici, $matches)) {
1758
				$ifinfo['laggproto'] = $matches[1];
1759
			}
1760
			if (preg_match("/laggport: (.*)$/", $ici, $matches)) {
1761
				$ifinfo['laggport'][] = $matches[1];
1762
			}
1763 fc455333 Viktor G
			if (preg_match("/plugged: (.*)$/", $ici, $matches)) {
1764 e4b4c3d2 Viktor G
				$ifinfo['plugged'] = $matches[1];
1765 fc455333 Viktor G
			}
1766
			if (preg_match("/vendor: (.*)$/", $ici, $matches)) {
1767 e4b4c3d2 Viktor G
				$ifinfo['vendor'] = $matches[1];
1768 fc455333 Viktor G
			}
1769
			if (preg_match("/module temperature: (.*) Voltage: (.*)$/", $ici, $matches)) {
1770 e4b4c3d2 Viktor G
				$ifinfo['temperature'] = $matches[1];
1771
				$ifinfo['voltage'] = $matches[2];
1772 fc455333 Viktor G
			}
1773
			if (preg_match("/RX: (.*) TX: (.*)$/", $ici, $matches)) {
1774 e4b4c3d2 Viktor G
				$ifinfo['rx'] = $matches[1];
1775
				$ifinfo['tx'] = $matches[2];
1776 fc455333 Viktor G
			}
1777 6189988d Scott Dale
		}
1778 23a193da Phil Davis
		foreach ($wifconfiginfo as $ici) {
1779 818a6b7d Seth Mos
			$elements = preg_split("/[ ]+/i", $ici);
1780
			if ($elements[0] != "") {
1781
				$ifinfo['bssid'] = $elements[0];
1782
			}
1783
			if ($elements[3] != "") {
1784
				$ifinfo['rate'] = $elements[3];
1785
			}
1786
			if ($elements[4] != "") {
1787
				$ifinfo['rssi'] = $elements[4];
1788
			}
1789
		}
1790 67ee1ec5 Ermal Luçi
		/* lookup the gateway */
1791 2bbb79cb Seth Mos
		if (interface_has_gateway($ifdescr)) {
1792 ebdbdbc2 gnhb
			$ifinfo['gateway'] = get_interface_gateway($ifdescr);
1793 0997d828 Viktor G
		}
1794
		if (interface_has_gatewayv6($ifdescr)) {
1795 2bbb79cb Seth Mos
			$ifinfo['gatewayv6'] = get_interface_gateway_v6($ifdescr);
1796
		}
1797 6189988d Scott Dale
	}
1798
1799
	$bridge = "";
1800 7ec05d27 Ermal Luçi
	$bridge = link_interface_to_bridge($ifdescr);
1801 23a193da Phil Davis
	if ($bridge) {
1802 6189988d Scott Dale
		$bridge_text = `/sbin/ifconfig {$bridge}`;
1803 23a193da Phil Davis
		if (stristr($bridge_text, "blocking") <> false) {
1804 7d1b238c Carlos Eduardo Ramos
			$ifinfo['bridge'] = "<b><font color='red'>" . gettext("blocking") . "</font></b> - " . gettext("check for ethernet loops");
1805 6189988d Scott Dale
			$ifinfo['bridgeint'] = $bridge;
1806 23a193da Phil Davis
		} else if (stristr($bridge_text, "learning") <> false) {
1807 7d1b238c Carlos Eduardo Ramos
			$ifinfo['bridge'] = gettext("learning");
1808 6189988d Scott Dale
			$ifinfo['bridgeint'] = $bridge;
1809 23a193da Phil Davis
		} else if (stristr($bridge_text, "forwarding") <> false) {
1810 7d1b238c Carlos Eduardo Ramos
			$ifinfo['bridge'] = gettext("forwarding");
1811 6189988d Scott Dale
			$ifinfo['bridgeint'] = $bridge;
1812
		}
1813
	}
1814
1815
	return $ifinfo;
1816
}
1817
1818
//returns cpu speed of processor. Good for determining capabilities of machine
1819
function get_cpu_speed() {
1820 971de1f9 Renato Botelho
	return get_single_sysctl("hw.clockrate");
1821 6189988d Scott Dale
}
1822 fab7ff44 Bill Marquette
1823 df0cb10b Phil Davis
function get_uptime_sec() {
1824
	$boottime = "";
1825
	$matches = "";
1826 971de1f9 Renato Botelho
	$boottime = get_single_sysctl("kern.boottime");
1827
	preg_match("/sec = (\d+)/", $boottime, $matches);
1828 df0cb10b Phil Davis
	$boottime = $matches[1];
1829 23a193da Phil Davis
	if (intval($boottime) == 0) {
1830 df0cb10b Phil Davis
		return 0;
1831 23a193da Phil Davis
	}
1832 df0cb10b Phil Davis
1833
	$uptime = time() - $boottime;
1834
	return $uptime;
1835
}
1836
1837 6e658d8d Viktor G
function resolve_host_addresses($host, $recordtypes = array(DNS_A, DNS_AAAA, DNS_CNAME), $index = true) {
1838
	$dnsresult = array();
1839
	$resolved = array();
1840
	$errreporting = error_reporting();
1841
	error_reporting($errreporting & ~E_WARNING);// dns_get_record throws a warning if nothing is resolved..
1842
	foreach ($recordtypes as $recordtype) {
1843
		$tmp = dns_get_record($host, $recordtype);
1844
		if (is_array($tmp)) {
1845
			$dnsresult = array_merge($dnsresult, $tmp);
1846
		}
1847
	}
1848
	error_reporting($errreporting);// restore original php warning/error settings.
1849
	foreach ($dnsresult as $item) {
1850
		$newitem = array();
1851
		$newitem['type'] = $item['type'];
1852
		switch ($item['type']) {
1853
			case 'CNAME':
1854
				$newitem['data'] = $item['target'];
1855
				$resolved[] = $newitem;
1856
				break;
1857
			case 'A':
1858
				$newitem['data'] = $item['ip'];
1859
				$resolved[] = $newitem;
1860
				break;
1861
			case 'AAAA':
1862
				$newitem['data'] = $item['ipv6'];
1863
				$resolved[] = $newitem;
1864
				break;
1865
		}
1866
	}
1867
	if ($index == false) {
1868
		foreach ($resolved as $res) {
1869
			$noind[] = $res['data'];
1870 477d5b5f Viktor Gurov
		}
1871 6e658d8d Viktor G
		$resolved = $noind;
1872 477d5b5f Viktor Gurov
	}
1873 6e658d8d Viktor G
	return $resolved;
1874 477d5b5f Viktor Gurov
}
1875
1876 a5f94f14 Scott Ullrich
function add_hostname_to_watch($hostname) {
1877 23a193da Phil Davis
	if (!is_dir("/var/db/dnscache")) {
1878 c941ea1c Seth Mos
		mkdir("/var/db/dnscache");
1879
	}
1880 2d0c5e3e Renato Botelho
	$result = array();
1881 23a193da Phil Davis
	if ((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1882 581e772e Seth Mos
		$contents = "";
1883 6e658d8d Viktor G
		$domips = resolve_host_addresses($hostname, array(DNS_A), false);
1884 23a193da Phil Davis
		if (!empty($domips)) {
1885
			foreach ($domips as $ip) {
1886 162c059e Seth Mos
				$contents .= "$ip\n";
1887
			}
1888 581e772e Seth Mos
		}
1889
		file_put_contents("/var/db/dnscache/$hostname", $contents);
1890 aa57f965 Renato Botelho
		/* Remove empty elements */
1891
		$result = array_filter(explode("\n", $contents), 'strlen');
1892 a5f94f14 Scott Ullrich
	}
1893 2d0c5e3e Renato Botelho
	return $result;
1894 a5f94f14 Scott Ullrich
}
1895
1896 5ed54b93 Seth Mos
function is_fqdn($fqdn) {
1897 7ea27240 Marco Pannetto
	return (bool) preg_match('/^(?:(?!-)[-_a-z0-9]+(?<!-)\.)*(?!-)[a-z0-9\-]+(?<!-)\.(?:xn--)?[a-z]+[\.]?$/i', $fqdn);
1898 5ed54b93 Seth Mos
}
1899
1900 639aaa95 Bill Marquette
function pfsense_default_state_size() {
1901 5fa78adc Renato Botelho
	/* get system memory amount */
1902
	$memory = get_memory();
1903 386758bb Phil Davis
	$physmem = $memory[0];
1904 5fa78adc Renato Botelho
	/* Be cautious and only allocate 10% of system memory to the state table */
1905 386758bb Phil Davis
	$max_states = (int) ($physmem/10)*1000;
1906 5fa78adc Renato Botelho
	return $max_states;
1907 639aaa95 Bill Marquette
}
1908
1909 84aea606 jim-p
function pfsense_default_tables_size() {
1910
	$current = `pfctl -sm | grep ^tables | awk '{print $4};'`;
1911
	return $current;
1912
}
1913
1914 fb586a16 jim-p
function pfsense_default_table_entries_size() {
1915
	$current = `pfctl -sm | grep table-entries | awk '{print $4};'`;
1916 742844a5 NOYB
	return (trim($current));
1917 fb586a16 jim-p
}
1918
1919 7723c7e0 Seth Mos
/* Compare the current hostname DNS to the DNS cache we made
1920
 * if it has changed we return the old records
1921 046b8ba6 Renato Botelho
 * if no change we return false */
1922 7723c7e0 Seth Mos
function compare_hostname_to_dnscache($hostname) {
1923 c239afac Reid Linnemann
	global $g;
1924 23a193da Phil Davis
	if (!is_dir("/var/db/dnscache")) {
1925 7723c7e0 Seth Mos
		mkdir("/var/db/dnscache");
1926
	}
1927
	$hostname = trim($hostname);
1928 23a193da Phil Davis
	if (is_readable("/var/db/dnscache/{$hostname}")) {
1929 7723c7e0 Seth Mos
		$oldcontents = file_get_contents("/var/db/dnscache/{$hostname}");
1930
	} else {
1931
		$oldcontents = "";
1932
	}
1933 23a193da Phil Davis
	if ((is_fqdn($hostname)) && (!is_ipaddr($hostname))) {
1934 7723c7e0 Seth Mos
		$contents = "";
1935 6e658d8d Viktor G
		$domips = resolve_host_addresses($hostname, array(DNS_A), false);
1936 23a193da Phil Davis
		if (!empty($domips)) {
1937
			foreach ($domips as $ip) {
1938 7723c7e0 Seth Mos
				$contents .= "$ip\n";
1939
			}
1940
		}
1941
	}
1942
1943 23a193da Phil Davis
	if (trim($oldcontents) != trim($contents)) {
1944 2568e151 Christian McDonald
		if (g_get('debug')) {
1945 addc0439 Renato Botelho
			log_error(sprintf(gettext('DNSCACHE: Found old IP %1$s and new IP %2$s'), $oldcontents, $contents));
1946 a5f91ef4 Seth Mos
		}
1947 7723c7e0 Seth Mos
		return ($oldcontents);
1948
	} else {
1949
		return false;
1950
	}
1951
}
1952
1953 09f18f59 jim-p
/*
1954 7530177c jim-p
 * load_crypto() - Load crypto modules if enabled in config.
1955 09f18f59 jim-p
 */
1956 7530177c jim-p
function load_crypto() {
1957 2c98383f jim-p
	$crypto_modules = array('aesni', 'cryptodev');
1958 7530177c jim-p
1959 364c9484 Reid Linnemann
	$enabled_modules = explode('_', config_get_path('system/crypto_hardware'));
1960 7530177c jim-p
1961 f96376a3 jim-p
	foreach ($enabled_modules as $enmod) {
1962
		if (empty($enmod) || !in_array($enmod, $crypto_modules)) {
1963
			continue;
1964
		}
1965
		if (!is_module_loaded($enmod)) {
1966
			log_error(sprintf(gettext("Loading %s cryptographic accelerator module."), $enmod));
1967 c66b71c8 Renato Botelho do Couto
			mute_kernel_msgs();
1968 f96376a3 jim-p
			mwexec("/sbin/kldload " . escapeshellarg($enmod));
1969 c66b71c8 Renato Botelho do Couto
			unmute_kernel_msgs();
1970 f96376a3 jim-p
		}
1971 09f18f59 jim-p
	}
1972
}
1973
1974 f60156f6 jim-p
/*
1975
 * load_thermal_hardware() - Load temperature monitor kernel module
1976
 */
1977
function load_thermal_hardware() {
1978
	$thermal_hardware_modules = array('coretemp', 'amdtemp');
1979 364c9484 Reid Linnemann
	$thermal_hardware = config_get_path('system/thermal_hardware');
1980 f60156f6 jim-p
1981 364c9484 Reid Linnemann
	if (!in_array($thermal_hardware, $thermal_hardware_modules)) {
1982 f60156f6 jim-p
		return false;
1983 23a193da Phil Davis
	}
1984 f60156f6 jim-p
1985 364c9484 Reid Linnemann
	if (!empty($thermal_hardware) && !is_module_loaded($thermal_hardware)) {
1986
		log_error(sprintf(gettext("Loading %s thermal monitor module."), $thermal_hardware));
1987 aabaad0a Viktor G
		mute_kernel_msgs();
1988 364c9484 Reid Linnemann
		mwexec("/sbin/kldload {$thermal_hardware}");
1989 aabaad0a Viktor G
		unmute_kernel_msgs();
1990 f60156f6 jim-p
	}
1991
}
1992
1993 cde4f5d3 Scott Ullrich
/****f* pfsense-utils/isvm
1994
 * NAME
1995
 *   isvm
1996
 * INPUTS
1997 c96e71d1 Renato Botelho
 *	none
1998 cde4f5d3 Scott Ullrich
 * RESULT
1999
 *   returns true if machine is running under a virtual environment
2000
 ******/
2001
function isvm() {
2002 7e36f71c Renato Botelho
	$virtualenvs = array("vmware", "parallels", "qemu", "bochs", "plex86", "VirtualBox");
2003 c239afac Reid Linnemann
	exec('/bin/kenv -q smbios.system.product 2>/dev/null', $output, $rc);
2004 7e36f71c Renato Botelho
2005 23a193da Phil Davis
	if ($rc != 0 || !isset($output[0])) {
2006 7e36f71c Renato Botelho
		return false;
2007 23a193da Phil Davis
	}
2008 7e36f71c Renato Botelho
2009 23a193da Phil Davis
	foreach ($virtualenvs as $virtualenv) {
2010
		if (stripos($output[0], $virtualenv) !== false) {
2011 58897b8c Warren Baker
			return true;
2012 23a193da Phil Davis
		}
2013
	}
2014 58897b8c Warren Baker
2015
	return false;
2016 cde4f5d3 Scott Ullrich
}
2017
2018 e0d0eb71 Scott Ullrich
function get_freebsd_version() {
2019 54597012 Renato Botelho
	$version = explode(".", php_uname("r"));
2020
	return $version[0];
2021 e0d0eb71 Scott Ullrich
}
2022
2023 a320af18 Chris Buechler
function download_file($url, $destination, $verify_ssl = true, $connect_timeout = 5, $timeout = 0) {
2024 364c9484 Reid Linnemann
	global $g;
2025 ffd7802a Renato Botelho
2026
	$fp = fopen($destination, "wb");
2027
2028 23a193da Phil Davis
	if (!$fp) {
2029 ffd7802a Renato Botelho
		return false;
2030 23a193da Phil Davis
	}
2031 ffd7802a Renato Botelho
2032
	$ch = curl_init();
2033
	curl_setopt($ch, CURLOPT_URL, $url);
2034 f03f7989 Marcos Mendoza
	if ($verify_ssl) {
2035
		curl_setopt($ch, CURLOPT_CAPATH, "/etc/ssl/certs/");
2036
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
2037
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
2038
	} else {
2039
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
2040
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
2041
		curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, false);
2042
	}
2043 ffd7802a Renato Botelho
	curl_setopt($ch, CURLOPT_FILE, $fp);
2044
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
2045
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
2046
	curl_setopt($ch, CURLOPT_HEADER, false);
2047
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
2048 364c9484 Reid Linnemann
	if (!config_path_enabled('system','do_not_send_uniqueid')) {
2049 2568e151 Christian McDonald
		curl_setopt($ch, CURLOPT_USERAGENT, g_get('product_label') . '/' . g_get('product_version') . ':' . system_get_uniqueid());
2050 6c07db48 Phil Davis
	} else {
2051 2568e151 Christian McDonald
		curl_setopt($ch, CURLOPT_USERAGENT, g_get('product_label') . '/' . g_get('product_version'));
2052 6c07db48 Phil Davis
	}
2053 ffd7802a Renato Botelho
2054 8b424bca Viktor G
	set_curlproxy($ch);
2055 ffd7802a Renato Botelho
2056
	@curl_exec($ch);
2057
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2058
	fclose($fp);
2059
	curl_close($ch);
2060 fd4dbabc Chris Buechler
	if ($http_code == 200) {
2061
		return true;
2062
	} else {
2063 e8c516a0 Phil Davis
		log_error(sprintf(gettext('Download file failed with status code %1$s. URL: %2$s'), $http_code, $url));
2064 fd4dbabc Chris Buechler
		unlink_if_exists($destination);
2065
		return false;
2066
	}
2067 ffd7802a Renato Botelho
}
2068
2069 eb38f9a8 Chris Buechler
function download_file_with_progress_bar($url, $destination, $verify_ssl = true, $readbody = 'read_body', $connect_timeout = 5, $timeout = 0) {
2070 364c9484 Reid Linnemann
	global $g, $ch, $fout, $file_size, $downloaded, $first_progress_update;
2071 4de8f7ba Phil Davis
	$file_size = 1;
2072 5fa78adc Renato Botelho
	$downloaded = 1;
2073 e961bd67 phildd
	$first_progress_update = TRUE;
2074 5fa78adc Renato Botelho
	/* open destination file */
2075 eb38f9a8 Chris Buechler
	$fout = fopen($destination, "wb");
2076 5fa78adc Renato Botelho
2077 eb38f9a8 Chris Buechler
	if (!$fout) {
2078
		return false;
2079
	}
2080 5fa78adc Renato Botelho
	/*
2081
	 *      Originally by Author: Keyvan Minoukadeh
2082
	 *      Modified by Scott Ullrich to return Content-Length size
2083
	 */
2084
	$ch = curl_init();
2085 eb38f9a8 Chris Buechler
	curl_setopt($ch, CURLOPT_URL, $url);
2086 f03f7989 Marcos Mendoza
	if ($verify_ssl) {
2087
		curl_setopt($ch, CURLOPT_CAPATH, "/etc/ssl/certs/");
2088
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
2089
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
2090
	} else {
2091
		curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
2092
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
2093
		curl_setopt($ch, CURLOPT_SSL_VERIFYSTATUS, false);
2094
	}
2095 5fa78adc Renato Botelho
	curl_setopt($ch, CURLOPT_HEADERFUNCTION, 'read_header');
2096
	curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
2097
	curl_setopt($ch, CURLOPT_WRITEFUNCTION, $readbody);
2098
	curl_setopt($ch, CURLOPT_NOPROGRESS, '1');
2099
	curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, $connect_timeout);
2100
	curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
2101 364c9484 Reid Linnemann
	if (!config_path_enabled('system','do_not_send_uniqueid')) {
2102 2568e151 Christian McDonald
		curl_setopt($ch, CURLOPT_USERAGENT, g_get('product_label') . '/' . g_get('product_version') . ':' . system_get_uniqueid());
2103 6c07db48 Phil Davis
	} else {
2104 2568e151 Christian McDonald
		curl_setopt($ch, CURLOPT_USERAGENT, g_get('product_label') . '/' . g_get('product_version'));
2105 6c07db48 Phil Davis
	}
2106 b31da21e Scott Ullrich
2107 8b424bca Viktor G
	set_curlproxy($ch);
2108 42c07003 Ermal
2109 5fa78adc Renato Botelho
	@curl_exec($ch);
2110
	$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
2111 eb38f9a8 Chris Buechler
	fclose($fout);
2112 5fa78adc Renato Botelho
	curl_close($ch);
2113 eb38f9a8 Chris Buechler
	if ($http_code == 200) {
2114
		return true;
2115
	} else {
2116 e8c516a0 Phil Davis
		log_error(sprintf(gettext('Download file failed with status code %1$s. URL: %2$s'), $http_code, $url));
2117 eb38f9a8 Chris Buechler
		unlink_if_exists($destination);
2118
		return false;
2119
	}
2120 b31da21e Scott Ullrich
}
2121
2122
function read_header($ch, $string) {
2123 c239afac Reid Linnemann
	global $file_size;
2124 5fa78adc Renato Botelho
	$length = strlen($string);
2125
	$regs = "";
2126
	preg_match("/(Content-Length:) (.*)/", $string, $regs);
2127 23a193da Phil Davis
	if ($regs[2] <> "") {
2128 5fa78adc Renato Botelho
		$file_size = intval($regs[2]);
2129
	}
2130
	ob_flush();
2131
	return $length;
2132 b31da21e Scott Ullrich
}
2133
2134
function read_body($ch, $string) {
2135 5fa78adc Renato Botelho
	global $fout, $file_size, $downloaded, $sendto, $static_status, $static_output, $lastseen, $first_progress_update;
2136
	global $pkg_interface;
2137
	$length = strlen($string);
2138
	$downloaded += intval($length);
2139 23a193da Phil Davis
	if ($file_size > 0) {
2140 5fa78adc Renato Botelho
		$downloadProgress = round(100 * (1 - $downloaded / $file_size), 0);
2141
		$downloadProgress = 100 - $downloadProgress;
2142 23a193da Phil Davis
	} else {
2143 5fa78adc Renato Botelho
		$downloadProgress = 0;
2144 23a193da Phil Davis
	}
2145
	if ($lastseen <> $downloadProgress and $downloadProgress < 101) {
2146
		if ($sendto == "status") {
2147
			if ($pkg_interface == "console") {
2148
				if (($downloadProgress % 10) == 0 || $downloadProgress < 10) {
2149 03b2cab6 Ermal
					$tostatus = $static_status . $downloadProgress . "%";
2150 2a315bee Phil Davis
					if ($downloadProgress == 100) {
2151 a3da8f50 Ermal
						$tostatus = $tostatus . "\r";
2152 2a315bee Phil Davis
					}
2153 03b2cab6 Ermal
					update_status($tostatus);
2154
				}
2155
			} else {
2156
				$tostatus = $static_status . $downloadProgress . "%";
2157 5fa78adc Renato Botelho
				update_status($tostatus);
2158 03b2cab6 Ermal
			}
2159 5fa78adc Renato Botelho
		} else {
2160 23a193da Phil Davis
			if ($pkg_interface == "console") {
2161
				if (($downloadProgress % 10) == 0 || $downloadProgress < 10) {
2162 03b2cab6 Ermal
					$tooutput = $static_output . $downloadProgress . "%";
2163 2a315bee Phil Davis
					if ($downloadProgress == 100) {
2164 a3da8f50 Ermal
						$tooutput = $tooutput . "\r";
2165 2a315bee Phil Davis
					}
2166 03b2cab6 Ermal
					update_output_window($tooutput);
2167
				}
2168
			} else {
2169
				$tooutput = $static_output . $downloadProgress . "%";
2170
				update_output_window($tooutput);
2171
			}
2172 5fa78adc Renato Botelho
		}
2173 23a193da Phil Davis
		if (($pkg_interface != "console") || (($downloadProgress % 10) == 0) || ($downloadProgress < 10)) {
2174
			update_progress_bar($downloadProgress, $first_progress_update);
2175
			$first_progress_update = FALSE;
2176
		}
2177 5fa78adc Renato Botelho
		$lastseen = $downloadProgress;
2178
	}
2179 23a193da Phil Davis
	if ($fout) {
2180 5fa78adc Renato Botelho
		fwrite($fout, $string);
2181 23a193da Phil Davis
	}
2182 5fa78adc Renato Botelho
	ob_flush();
2183
	return $length;
2184 b31da21e Scott Ullrich
}
2185
2186 84677257 Scott Ullrich
/*
2187
 *   update_output_window: update bottom textarea dynamically.
2188
 */
2189
function update_output_window($text) {
2190 5fa78adc Renato Botelho
	global $pkg_interface;
2191
	$log = preg_replace("/\n/", "\\n", $text);
2192 23a193da Phil Davis
	if ($pkg_interface != "console") {
2193 2d26ee5e Sjon Hortensius
?>
2194 8fd9052f Colin Fleming
<script type="text/javascript">
2195
//<![CDATA[
2196 2d26ee5e Sjon Hortensius
	document.getElementById("output").textContent="<?=htmlspecialchars($log)?>";
2197
	document.getElementById("output").scrollTop = document.getElementById("output").scrollHeight;
2198 8fd9052f Colin Fleming
//]]>
2199 2d26ee5e Sjon Hortensius
</script>
2200
<?php
2201 5fa78adc Renato Botelho
	}
2202
	/* ensure that contents are written out */
2203
	ob_flush();
2204 84677257 Scott Ullrich
}
2205
2206
/*
2207 82acb8b3 Phil Davis
 *   update_status: update top textarea dynamically.
2208 84677257 Scott Ullrich
 */
2209
function update_status($status) {
2210 5fa78adc Renato Botelho
	global $pkg_interface;
2211 1da49511 Renato Botelho
2212 23a193da Phil Davis
	if ($pkg_interface == "console") {
2213 489c102b BBcan177
		print ("{$status}");
2214 5fa78adc Renato Botelho
	}
2215 2d26ee5e Sjon Hortensius
2216 5fa78adc Renato Botelho
	/* ensure that contents are written out */
2217
	ob_flush();
2218 84677257 Scott Ullrich
}
2219
2220
/*
2221 e961bd67 phildd
 * update_progress_bar($percent, $first_time): updates the javascript driven progress bar.
2222 84677257 Scott Ullrich
 */
2223 e961bd67 phildd
function update_progress_bar($percent, $first_time) {
2224 5fa78adc Renato Botelho
	global $pkg_interface;
2225 23a193da Phil Davis
	if ($percent > 100) {
2226
		$percent = 1;
2227
	}
2228
	if ($pkg_interface <> "console") {
2229 8fd9052f Colin Fleming
		echo '<script type="text/javascript">';
2230
		echo "\n//<![CDATA[\n";
2231 66066eda Stephen Beaver
		echo 'document.getElementById("progressbar").style.width="'. $percent.'%"';
2232 8fd9052f Colin Fleming
		echo "\n//]]>\n";
2233
		echo '</script>';
2234 5fa78adc Renato Botelho
	} else {
2235 23a193da Phil Davis
		if (!($first_time)) {
2236 e961bd67 phildd
			echo "\x08\x08\x08\x08\x08";
2237 23a193da Phil Davis
		}
2238 e961bd67 phildd
		echo sprintf("%4d%%", $percent);
2239 5fa78adc Renato Botelho
	}
2240 84677257 Scott Ullrich
}
2241
2242 24807bfe Phil Davis
function update_alias_name($new_alias_name, $orig_alias_name) {
2243
	if (!$orig_alias_name) {
2244
		return;
2245
	}
2246
2247
	// Firewall rules
2248
	update_alias_names_upon_change(array('filter', 'rule'), array('source', 'address'), $new_alias_name, $orig_alias_name);
2249
	update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'address'), $new_alias_name, $orig_alias_name);
2250
	update_alias_names_upon_change(array('filter', 'rule'), array('source', 'port'), $new_alias_name, $orig_alias_name);
2251
	update_alias_names_upon_change(array('filter', 'rule'), array('destination', 'port'), $new_alias_name, $orig_alias_name);
2252
	// NAT Rules
2253
	update_alias_names_upon_change(array('nat', 'rule'), array('source', 'address'), $new_alias_name, $orig_alias_name);
2254
	update_alias_names_upon_change(array('nat', 'rule'), array('source', 'port'), $new_alias_name, $orig_alias_name);
2255
	update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'address'), $new_alias_name, $orig_alias_name);
2256
	update_alias_names_upon_change(array('nat', 'rule'), array('destination', 'port'), $new_alias_name, $orig_alias_name);
2257
	update_alias_names_upon_change(array('nat', 'rule'), array('target'), $new_alias_name, $orig_alias_name);
2258
	update_alias_names_upon_change(array('nat', 'rule'), array('local-port'), $new_alias_name, $orig_alias_name);
2259
	// NAT 1:1 Rules
2260
	//update_alias_names_upon_change(array('nat', 'onetoone'), array('external'), $new_alias_name, $orig_alias_name);
2261
	//update_alias_names_upon_change(array('nat', 'onetoone'), array('source', 'address'), $new_alias_name, $orig_alias_name);
2262
	update_alias_names_upon_change(array('nat', 'onetoone'), array('destination', 'address'), $new_alias_name, $orig_alias_name);
2263
	// NAT Outbound Rules
2264
	update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('source', 'network'), $new_alias_name, $orig_alias_name);
2265
	update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('sourceport'), $new_alias_name, $orig_alias_name);
2266
	update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('destination', 'address'), $new_alias_name, $orig_alias_name);
2267
	update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('dstport'), $new_alias_name, $orig_alias_name);
2268
	update_alias_names_upon_change(array('nat', 'outbound', 'rule'), array('target'), $new_alias_name, $orig_alias_name);
2269
	// Alias in an alias
2270
	update_alias_names_upon_change(array('aliases', 'alias'), array('address'), $new_alias_name, $orig_alias_name);
2271 b979719f Viktor G
	// Static routes
2272
	update_alias_names_upon_change(array('staticroutes', 'route'), array('network'), $new_alias_name, $orig_alias_name);
2273
	// OpenVPN
2274
	update_alias_names_upon_change(array('openvpn', 'openvpn-server'), array('tunnel_network'), $new_alias_name, $orig_alias_name);
2275
	update_alias_names_upon_change(array('openvpn', 'openvpn-server'), array('tunnel_networkv6'), $new_alias_name, $orig_alias_name);
2276
	update_alias_names_upon_change(array('openvpn', 'openvpn-server'), array('local_network'), $new_alias_name, $orig_alias_name);
2277
	update_alias_names_upon_change(array('openvpn', 'openvpn-server'), array('local_networkv6'), $new_alias_name, $orig_alias_name);
2278
	update_alias_names_upon_change(array('openvpn', 'openvpn-server'), array('remote_network'), $new_alias_name, $orig_alias_name);
2279
	update_alias_names_upon_change(array('openvpn', 'openvpn-server'), array('remote_networkv6'), $new_alias_name, $orig_alias_name);
2280
	update_alias_names_upon_change(array('openvpn', 'openvpn-client'), array('tunnel_network'), $new_alias_name, $orig_alias_name);
2281
	update_alias_names_upon_change(array('openvpn', 'openvpn-client'), array('tunnel_networkv6'), $new_alias_name, $orig_alias_name);
2282
	update_alias_names_upon_change(array('openvpn', 'openvpn-client'), array('remote_network'), $new_alias_name, $orig_alias_name);
2283
	update_alias_names_upon_change(array('openvpn', 'openvpn-client'), array('remote_networkv6'), $new_alias_name, $orig_alias_name);
2284
	update_alias_names_upon_change(array('openvpn', 'openvpn-csc'), array('tunnel_network'), $new_alias_name, $orig_alias_name);
2285
	update_alias_names_upon_change(array('openvpn', 'openvpn-csc'), array('tunnel_networkv6'), $new_alias_name, $orig_alias_name);
2286
	update_alias_names_upon_change(array('openvpn', 'openvpn-csc'), array('local_network'), $new_alias_name, $orig_alias_name);
2287
	update_alias_names_upon_change(array('openvpn', 'openvpn-csc'), array('local_networkv6'), $new_alias_name, $orig_alias_name);
2288
	update_alias_names_upon_change(array('openvpn', 'openvpn-csc'), array('remote_network'), $new_alias_name, $orig_alias_name);
2289
	update_alias_names_upon_change(array('openvpn', 'openvpn-csc'), array('remote_networkv6'), $new_alias_name, $orig_alias_name);
2290 24807bfe Phil Davis
}
2291
2292 f1ac1733 Erik Fonnesbeck
function update_alias_names_upon_change($section, $field, $new_alias_name, $origname) {
2293 978fd2e8 Scott Ullrich
	global $g, $config, $pconfig, $debug;
2294 23a193da Phil Davis
	if (!$origname) {
2295 b6db8ea3 sullrich
		return;
2296 23a193da Phil Davis
	}
2297 b6db8ea3 sullrich
2298 f1ac1733 Erik Fonnesbeck
	$sectionref = &$config;
2299 23a193da Phil Davis
	foreach ($section as $sectionname) {
2300
		if (is_array($sectionref) && isset($sectionref[$sectionname])) {
2301 f1ac1733 Erik Fonnesbeck
			$sectionref = &$sectionref[$sectionname];
2302 23a193da Phil Davis
		} else {
2303 f1ac1733 Erik Fonnesbeck
			return;
2304 23a193da Phil Davis
		}
2305 f1ac1733 Erik Fonnesbeck
	}
2306
2307 23a193da Phil Davis
	if ($debug) {
2308
		$fd = fopen("{$g['tmp_path']}/print_r", "a");
2309
		fwrite($fd, print_r($pconfig, true));
2310
	}
2311 b6db8ea3 sullrich
2312 23a193da Phil Davis
	if (is_array($sectionref)) {
2313 c239afac Reid Linnemann
		foreach (array_keys($sectionref) as $itemkey) {
2314 23a193da Phil Davis
			if ($debug) {
2315
				fwrite($fd, "$itemkey\n");
2316
			}
2317 f1ac1733 Erik Fonnesbeck
2318
			$fieldfound = true;
2319
			$fieldref = &$sectionref[$itemkey];
2320 23a193da Phil Davis
			foreach ($field as $fieldname) {
2321
				if (is_array($fieldref) && isset($fieldref[$fieldname])) {
2322 f1ac1733 Erik Fonnesbeck
					$fieldref = &$fieldref[$fieldname];
2323 23a193da Phil Davis
				} else {
2324 f1ac1733 Erik Fonnesbeck
					$fieldfound = false;
2325
					break;
2326
				}
2327 b6db8ea3 sullrich
			}
2328 23a193da Phil Davis
			if ($fieldfound && $fieldref == $origname) {
2329
				if ($debug) {
2330
					fwrite($fd, "Setting old alias value $origname to $new_alias_name\n");
2331
				}
2332 f1ac1733 Erik Fonnesbeck
				$fieldref = $new_alias_name;
2333 b6db8ea3 sullrich
			}
2334
		}
2335
	}
2336
2337 23a193da Phil Davis
	if ($debug) {
2338
		fclose($fd);
2339
	}
2340 b6db8ea3 sullrich
2341
}
2342 f6ba4bd1 Scott Ullrich
2343 f6622167 NOYB
function parse_aliases_file($filename, $type = "url", $max_items = -1, $kflc = false) {
2344 6d1907a3 Renato Botelho
	/*
2345
	 * $filename = file to process for example blocklist like DROP:  http://www.spamhaus.org/drop/drop.txt
2346
	 * $type = if set to 'url' then subnets and ips will be returned,
2347
	 *         if set to 'url_ports' port-ranges and ports will be returned
2348
	 * $max_items = sets the maximum amount of valid items to load, -1 the default defines there is no limit.
2349
	 *
2350
	 * RETURNS an array of ip subnets and ip's or ports and port-ranges, returns NULL upon a error conditions (file not found)
2351
	 */
2352
2353 14645549 Chris Buechler
	if (!file_exists($filename)) {
2354
		log_error(sprintf(gettext("Could not process non-existent file from alias: %s"), $filename));
2355
		return null;
2356
	}
2357
2358 6f838722 Chris Buechler
	if (filesize($filename) == 0) {
2359
		log_error(sprintf(gettext("Could not process empty file from alias: %s"), $filename));
2360
		return null;
2361
	}
2362 6d1907a3 Renato Botelho
	$fd = @fopen($filename, 'r');
2363
	if (!$fd) {
2364 e8c516a0 Phil Davis
		log_error(sprintf(gettext("Could not process aliases from alias: %s"), $filename));
2365 6d1907a3 Renato Botelho
		return null;
2366
	}
2367
	$items = array();
2368 f6622167 NOYB
	$comments = array();
2369 af613468 jim-p
	while (($fc = fgets($fd)) !== FALSE) {
2370
		$fc = strip_tags($fc);
2371 c91be02b Viktor G
		$tmp = alias_idn_to_ascii(trim($fc, " \t\n\r"));
2372 23a193da Phil Davis
		if (empty($tmp)) {
2373 6d1907a3 Renato Botelho
			continue;
2374 23a193da Phil Davis
		}
2375 f6622167 NOYB
		if (($kflc) && (strpos($tmp, '#') === 0)) {	// Keep Full Line Comments (lines beginning with #).
2376
			$comments[] = $tmp;
2377
		} else {
2378
			$tmp_str = strstr($tmp, '#', true);
2379
			if (!empty($tmp_str)) {
2380
				$tmp = $tmp_str;
2381
			}
2382
			$tmp_str = strstr($tmp, ' ', true);
2383
			if (!empty($tmp_str)) {
2384
				$tmp = $tmp_str;
2385
			}
2386 477d5b5f Viktor Gurov
			switch ($type) {
2387
				case "url":
2388
				case "urltable":
2389
					if (is_ipaddr($tmp) || is_subnet($tmp)) {
2390
						$items[] = $tmp;
2391
						break;
2392
					}
2393
					if (is_fqdn($tmp)) {
2394 6e658d8d Viktor G
						$results = resolve_host_addresses($tmp, array(DNS_A, DNS_AAAA), false);
2395 477d5b5f Viktor Gurov
						if (!empty($results)) {
2396
							foreach ($results as $ip) {
2397
								if (is_ipaddr($ip)) {
2398
									$items[] = $ip;
2399
								}
2400
							}
2401
						}
2402
					}
2403
					break;
2404
				case "url_ports":
2405
				case "urltable_ports":
2406
					if (is_port_or_range($tmp)) {
2407
						$items[] = $tmp;
2408
					}
2409
					break;
2410
				default:
2411
					/* unknown type */
2412 f6622167 NOYB
					break;
2413
				}
2414 477d5b5f Viktor Gurov
			if (count($items) == $max_items) {
2415
				break;
2416 23a193da Phil Davis
			}
2417 6d1907a3 Renato Botelho
		}
2418
	}
2419
	fclose($fd);
2420 f6622167 NOYB
	return array_merge($comments, $items);
2421 6d1907a3 Renato Botelho
}
2422
2423 f6ba4bd1 Scott Ullrich
function update_alias_url_data() {
2424 364c9484 Reid Linnemann
	global $g, $aliastable;
2425 e5953c68 Ermal
2426 8422cdd5 Ermal
	$updated = false;
2427
2428 f6ba4bd1 Scott Ullrich
	/* item is a url type */
2429 8422cdd5 Ermal
	$lockkey = lock('aliasurl');
2430 364c9484 Reid Linnemann
	$aliases = array();
2431
	$aliases_nested = array();
2432 923399be Viktor G
2433 364c9484 Reid Linnemann
	foreach (config_get_path('aliases/alias', []) as $x => $alias) {
2434
		if (empty($alias['aliasurl'])) {
2435
			continue;
2436
		}
2437
		foreach ($alias['aliasurl'] as $alias_url) {
2438
			if (is_alias($alias_url)) {
2439
				// process nested URL aliases after URL-only aliases
2440
				$aliases_nested[] = $x;
2441
				continue 2;
2442 923399be Viktor G
			}
2443
		}
2444 364c9484 Reid Linnemann
		$aliases[] = $x;
2445
	}
2446 923399be Viktor G
2447 364c9484 Reid Linnemann
	foreach (array_merge($aliases, $aliases_nested) as $x) {
2448 76590ffe Renato Botelho
2449 364c9484 Reid Linnemann
		$address = array();
2450
		$type = config_get_path("aliases/alias/{$x}/type");
2451
		foreach (config_get_path("aliases/alias/{$x}/aliasurl") as $alias_url) {
2452
			/* fetch down and add in */
2453
			if (is_URL($alias_url)) {
2454
				$temp_filename = tempnam("{$g['tmp_path']}/", "alias_import");
2455
				rmdir_recursive($temp_filename);
2456
				$verify_ssl = config_path_enabled('system','checkaliasesurlcert');
2457
				mkdir($temp_filename);
2458
				if (!download_file($alias_url, $temp_filename . "/aliases", $verify_ssl)) {
2459
					log_error(sprintf(gettext("Failed to download alias %s"), $alias_url));
2460 923399be Viktor G
					rmdir_recursive($temp_filename);
2461 364c9484 Reid Linnemann
					continue;
2462
				}
2463 923399be Viktor G
2464 364c9484 Reid Linnemann
				/* if the item is tar gzipped then extract */
2465
				if (stripos($alias_url, '.tgz') && !process_alias_tgz($temp_filename)) {
2466
					log_error(sprintf(gettext("Could not unpack tgz from the URL '%s'."), $alias_url));
2467 923399be Viktor G
					rmdir_recursive($temp_filename);
2468 364c9484 Reid Linnemann
					continue;
2469
				}
2470
				if (file_exists("{$temp_filename}/aliases")) {
2471
					$t_address = parse_aliases_file("{$temp_filename}/aliases", $type, 5000);
2472 923399be Viktor G
					if ($t_address == null) {
2473 364c9484 Reid Linnemann
						/* nothing was found */
2474
						log_error(sprintf(gettext("Could not fetch usable data from '%s'."), $alias_url));
2475
						//rmdir_recursive($temp_filename);
2476 923399be Viktor G
						continue;
2477 364c9484 Reid Linnemann
					} else {
2478
						array_push($address, ...$t_address);
2479 923399be Viktor G
					}
2480 364c9484 Reid Linnemann
					unset($t_address);
2481
				}
2482
				rmdir_recursive($temp_filename);
2483
			} elseif (is_alias($alias_url)) {
2484
				/* nested URL alias, see https://redmine.pfsense.org/issues/11863 */
2485
				if (!$aliastable) {
2486
					alias_make_table();
2487 e45bae34 Ermal
				}
2488 364c9484 Reid Linnemann
				$t_address = explode(" ", $aliastable[$alias_url]);
2489
				if ($t_address == null) {
2490
					log_error(sprintf(gettext("Could not get usable data from '%s' URL alias."), $alias_url));
2491
					continue;
2492 f6ba4bd1 Scott Ullrich
				}
2493 364c9484 Reid Linnemann
				array_push($address, ...$t_address);
2494
			}
2495
			if (!empty($address)) {
2496
				config_set_path("aliases/alias/{$x}/address", implode(" ", $address));
2497
				$updated = true;
2498 2ef16014 bcyrill
			}
2499 f6ba4bd1 Scott Ullrich
		}
2500
	}
2501 364c9484 Reid Linnemann
2502 26d060bc Ermal
	unlock($lockkey);
2503 8422cdd5 Ermal
2504
	/* Report status to callers as well */
2505
	return $updated;
2506 f6ba4bd1 Scott Ullrich
}
2507
2508
function process_alias_tgz($temp_filename) {
2509 23a193da Phil Davis
	if (!file_exists('/usr/bin/tar')) {
2510 e45bae34 Ermal
		log_error(gettext("Alias archive is a .tar/tgz file which cannot be decompressed because utility is missing!"));
2511
		return false;
2512
	}
2513 873c1701 Renato Botelho
	rename("{$temp_filename}/aliases", "{$temp_filename}/aliases.tgz");
2514 f6ba4bd1 Scott Ullrich
	mwexec("/usr/bin/tar xzf {$temp_filename}/aliases.tgz -C {$temp_filename}/aliases/");
2515
	unlink("{$temp_filename}/aliases.tgz");
2516
	$files_to_process = return_dir_as_array("{$temp_filename}/");
2517
	/* foreach through all extracted files and build up aliases file */
2518 e45bae34 Ermal
	$fd = @fopen("{$temp_filename}/aliases", "w");
2519
	if (!$fd) {
2520 e8c516a0 Phil Davis
		log_error(sprintf(gettext("Could not open %s/aliases for writing!"), $temp_filename));
2521 e45bae34 Ermal
		return false;
2522
	}
2523 23a193da Phil Davis
	foreach ($files_to_process as $f2p) {
2524 e45bae34 Ermal
		$tmpfd = @fopen($f2p, 'r');
2525
		if (!$tmpfd) {
2526 e8c516a0 Phil Davis
			log_error(sprintf(gettext('The following file could not be read %1$s from %2$s'), $f2p, $temp_filename));
2527 e45bae34 Ermal
			continue;
2528
		}
2529 23a193da Phil Davis
		while (($tmpbuf = fread($tmpfd, 65536)) !== FALSE) {
2530 e45bae34 Ermal
			fwrite($fd, $tmpbuf);
2531 23a193da Phil Davis
		}
2532 e45bae34 Ermal
		fclose($tmpfd);
2533 f6ba4bd1 Scott Ullrich
		unlink($f2p);
2534
	}
2535
	fclose($fd);
2536 e45bae34 Ermal
	unset($tmpbuf);
2537
2538
	return true;
2539 f6ba4bd1 Scott Ullrich
}
2540
2541 a76c1c45 jim-p
function version_compare_dates($a, $b) {
2542
	$a_time = strtotime($a);
2543
	$b_time = strtotime($b);
2544
2545
	if ((!$a_time) || (!$b_time)) {
2546
		return FALSE;
2547
	} else {
2548 23a193da Phil Davis
		if ($a_time < $b_time) {
2549 a76c1c45 jim-p
			return -1;
2550 23a193da Phil Davis
		} elseif ($a_time == $b_time) {
2551 a76c1c45 jim-p
			return 0;
2552 23a193da Phil Davis
		} else {
2553 a76c1c45 jim-p
			return 1;
2554 23a193da Phil Davis
		}
2555 a76c1c45 jim-p
	}
2556
}
2557
function version_get_string_value($a) {
2558
	$strs = array(
2559
		0 => "ALPHA-ALPHA",
2560
		2 => "ALPHA",
2561
		3 => "BETA",
2562
		4 => "B",
2563 5eb03383 jim-p
		5 => "C",
2564
		6 => "D",
2565
		7 => "RC",
2566 f8c8d65c Stilez
		8 => "RELEASE",
2567
		9 => "*"			// Matches all release levels
2568 a76c1c45 jim-p
	);
2569
	$major = 0;
2570
	$minor = 0;
2571
	foreach ($strs as $num => $str) {
2572
		if (substr($a, 0, strlen($str)) == $str) {
2573
			$major = $num;
2574
			$n = substr($a, strlen($str));
2575 23a193da Phil Davis
			if (is_numeric($n)) {
2576 a76c1c45 jim-p
				$minor = $n;
2577 23a193da Phil Davis
			}
2578 a76c1c45 jim-p
			break;
2579
		}
2580
	}
2581
	return "{$major}.{$minor}";
2582
}
2583
function version_compare_string($a, $b) {
2584 f8c8d65c Stilez
	// Only compare string parts if both versions give a specific release
2585
	// (If either version lacks a string part, assume intended to match all release levels)
2586 23a193da Phil Davis
	if (isset($a) && isset($b)) {
2587 c96e71d1 Renato Botelho
		return version_compare_numeric(version_get_string_value($a), version_get_string_value($b));
2588 23a193da Phil Davis
	} else {
2589 c96e71d1 Renato Botelho
		return 0;
2590 23a193da Phil Davis
	}
2591 a76c1c45 jim-p
}
2592
function version_compare_numeric($a, $b) {
2593 48081e6c Phil Davis
	$a_arr = explode('.', rtrim($a, '.'));
2594
	$b_arr = explode('.', rtrim($b, '.'));
2595 a76c1c45 jim-p
2596
	foreach ($a_arr as $n => $val) {
2597
		if (array_key_exists($n, $b_arr)) {
2598
			// So far so good, both have values at this minor version level. Compare.
2599 23a193da Phil Davis
			if ($val > $b_arr[$n]) {
2600 a76c1c45 jim-p
				return 1;
2601 23a193da Phil Davis
			} elseif ($val < $b_arr[$n]) {
2602 a76c1c45 jim-p
				return -1;
2603 23a193da Phil Davis
			}
2604 a76c1c45 jim-p
		} else {
2605
			// a is greater, since b doesn't have any minor version here.
2606
			return 1;
2607
		}
2608
	}
2609
	if (count($b_arr) > count($a_arr)) {
2610
		// b is longer than a, so it must be greater.
2611
		return -1;
2612
	} else {
2613
		// Both a and b are of equal length and value.
2614
		return 0;
2615
	}
2616
}
2617
function pfs_version_compare($cur_time, $cur_text, $remote) {
2618
	// First try date compare
2619 bda131b2 jim-p
	$v = version_compare_dates($cur_time, $remote);
2620 a76c1c45 jim-p
	if ($v === FALSE) {
2621
		// If that fails, try to compare by string
2622
		// Before anything else, simply test if the strings are equal
2623 23a193da Phil Davis
		if (($cur_text == $remote) || ($cur_time == $remote)) {
2624 a76c1c45 jim-p
			return 0;
2625 23a193da Phil Davis
		}
2626 a76c1c45 jim-p
		list($cur_num, $cur_str) = explode('-', $cur_text);
2627
		list($rem_num, $rem_str) = explode('-', $remote);
2628
2629
		// First try to compare the numeric parts of the version string.
2630
		$v = version_compare_numeric($cur_num, $rem_num);
2631
2632
		// If the numeric parts are the same, compare the string parts.
2633 23a193da Phil Davis
		if ($v == 0) {
2634 a76c1c45 jim-p
			return version_compare_string($cur_str, $rem_str);
2635 23a193da Phil Davis
		}
2636 a76c1c45 jim-p
	}
2637
	return $v;
2638
}
2639 3b07f4fe NOYB
function process_alias_urltable($name, $type, $url, $freq, $forceupdate=false, $validateonly=false) {
2640 364c9484 Reid Linnemann
	global $g;
2641 dd042c51 Renato Botelho
2642 c239afac Reid Linnemann
	if (!is_validaliasname($name) || !filter_var($url, FILTER_VALIDATE_URL)) {
2643 db0cdbc8 jim-p
		return false;
2644
	}
2645
2646 c7de8be4 jim-p
	$urltable_prefix = "/var/db/aliastables/";
2647 db0cdbc8 jim-p
	$urltable_filename = $urltable_prefix . basename($name) . ".txt";
2648 e9fea9dc Chris Buechler
	$tmp_urltable_filename = $urltable_filename . ".tmp";
2649 c7de8be4 jim-p
2650
	// Make the aliases directory if it doesn't exist
2651
	if (!file_exists($urltable_prefix)) {
2652
		mkdir($urltable_prefix);
2653
	} elseif (!is_dir($urltable_prefix)) {
2654
		unlink($urltable_prefix);
2655
		mkdir($urltable_prefix);
2656
	}
2657
2658
	// If the file doesn't exist or is older than update_freq days, fetch a new copy.
2659 cc293ac0 Chris Buechler
	if (!file_exists($urltable_filename) || (filesize($urltable_filename) == "0") ||
2660 23a193da Phil Davis
	    ((time() - filemtime($urltable_filename)) > ($freq * 86400 - 90)) ||
2661
	    $forceupdate) {
2662 c7de8be4 jim-p
2663
		// Try to fetch the URL supplied
2664 e9fea9dc Chris Buechler
		unlink_if_exists($tmp_urltable_filename);
2665 364c9484 Reid Linnemann
		$verify_ssl = config_path_enabled('system','checkaliasesurlcert');
2666 e9fea9dc Chris Buechler
		if (download_file($url, $tmp_urltable_filename, $verify_ssl)) {
2667 f6622167 NOYB
			// Convert lines that begin with '$' or ';' to comments '#' instead of deleting them.
2668
			mwexec("/usr/bin/sed -i \"\" -E 's/^[[:space:]]*($|#|;)/#/g; /^#/!s/\;.*//g;' ". escapeshellarg($tmp_urltable_filename));
2669 ebe833f6 NOYB
2670 3b07f4fe NOYB
			$type = ($type) ? $type : alias_get_type($name);	// If empty type passed, try to get it from config.
2671 ebe833f6 NOYB
2672
			$parsed_contents = parse_aliases_file($tmp_urltable_filename, $type, "-1", true);
2673 f42ef69a NOYB
			if ($type == "urltable_ports") {
2674 ebe833f6 NOYB
				$parsed_contents = group_ports($parsed_contents, true);
2675
			}
2676
			if (is_array($parsed_contents)) {
2677
				file_put_contents($urltable_filename, implode("\n", $parsed_contents));
2678 e5581024 Chris Buechler
			} else {
2679
				touch($urltable_filename);
2680 dd042c51 Renato Botelho
			}
2681 ebe833f6 NOYB
2682 08696051 NOYB
			/* Remove existing archive and create an up to date archive if RAM disk is enabled. */
2683
			unlink_if_exists("{$g['cf_conf_path']}/RAM_Disk_Store/{$name}.txt.tgz");
2684 364c9484 Reid Linnemann
			if (config_path_enabled('system','use_mfs_tmpvar') && !file_exists("/conf/ram_disks_failed")) {
2685 257d2fd6 NOYB
				mwexec("/usr/bin/tar -czf " . escapeshellarg("{$g['cf_conf_path']}/RAM_Disk_Store/{$name}.txt.tgz") . " -C / " . escapeshellarg($urltable_filename));
2686 03afdafa NOYB
			}
2687 08696051 NOYB
2688 e9fea9dc Chris Buechler
			unlink_if_exists($tmp_urltable_filename);
2689 23a193da Phil Davis
		} else {
2690 b913daf8 Chris Buechler
			if (!$validateonly) {
2691
				touch($urltable_filename);
2692
			}
2693 ca46f1de Chris Buechler
			return false;
2694 23a193da Phil Davis
		}
2695 966f359e Ermal
		return true;
2696 c7de8be4 jim-p
	} else {
2697 23a193da Phil Davis
		// File exists, and it doesn't need to be updated.
2698 c7de8be4 jim-p
		return -1;
2699
	}
2700
}
2701 26c8cc72 jim-p
2702 38080cc1 Scott Ullrich
function get_include_contents($filename) {
2703 5fa78adc Renato Botelho
	if (is_file($filename)) {
2704
		ob_start();
2705
		include $filename;
2706
		$contents = ob_get_contents();
2707
		ob_end_clean();
2708
		return $contents;
2709
	}
2710
	return false;
2711 38080cc1 Scott Ullrich
}
2712
2713 3ffa8318 Renato Botelho
/* This xml 2 array function is courtesy of the php.net comment section on xml_parse.
2714
 * it is roughly 4 times faster then our existing pfSense parser but due to the large
2715
 * size of the RRD xml dumps this is required.
2716
 * The reason we do not use it for pfSense is that it does not know about array fields
2717
 * which causes it to fail on array fields with single items. Possible Todo?
2718
 */
2719 086cf944 Phil Davis
function xml2array($contents, $get_attributes = 1, $priority = 'tag') {
2720 23a193da Phil Davis
	if (!function_exists('xml_parser_create')) {
2721 86c707f3 Darren Embry
		return array ();
2722
	}
2723
	$parser = xml_parser_create('');
2724
	xml_parser_set_option($parser, XML_OPTION_TARGET_ENCODING, "UTF-8");
2725
	xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
2726
	xml_parser_set_option($parser, XML_OPTION_SKIP_WHITE, 1);
2727
	xml_parse_into_struct($parser, trim($contents), $xml_values);
2728
	xml_parser_free($parser);
2729 23a193da Phil Davis
	if (!$xml_values) {
2730 86c707f3 Darren Embry
		return; //Hmm...
2731 23a193da Phil Davis
	}
2732 86c707f3 Darren Embry
	$xml_array = array ();
2733
	$parents = array ();
2734
	$opened_tags = array ();
2735
	$arr = array ();
2736
	$current = & $xml_array;
2737
	$repeated_tag_index = array ();
2738 23a193da Phil Davis
	foreach ($xml_values as $data) {
2739 86c707f3 Darren Embry
		unset ($attributes, $value);
2740
		extract($data);
2741
		$result = array ();
2742
		$attributes_data = array ();
2743 23a193da Phil Davis
		if (isset ($value)) {
2744
			if ($priority == 'tag') {
2745 86c707f3 Darren Embry
				$result = $value;
2746 23a193da Phil Davis
			} else {
2747 86c707f3 Darren Embry
				$result['value'] = $value;
2748 23a193da Phil Davis
			}
2749 86c707f3 Darren Embry
		}
2750 23a193da Phil Davis
		if (isset ($attributes) and $get_attributes) {
2751
			foreach ($attributes as $attr => $val) {
2752
				if ($priority == 'tag') {
2753 86c707f3 Darren Embry
					$attributes_data[$attr] = $val;
2754 23a193da Phil Davis
				} else {
2755 86c707f3 Darren Embry
					$result['attr'][$attr] = $val; //Set all the attributes in a array called 'attr'
2756 23a193da Phil Davis
				}
2757 86c707f3 Darren Embry
			}
2758
		}
2759 23a193da Phil Davis
		if ($type == "open") {
2760 86c707f3 Darren Embry
			$parent[$level -1] = & $current;
2761 23a193da Phil Davis
			if (!is_array($current) or (!in_array($tag, array_keys($current)))) {
2762 86c707f3 Darren Embry
				$current[$tag] = $result;
2763 23a193da Phil Davis
				if ($attributes_data) {
2764 86c707f3 Darren Embry
					$current[$tag . '_attr'] = $attributes_data;
2765 23a193da Phil Davis
				}
2766 86c707f3 Darren Embry
				$repeated_tag_index[$tag . '_' . $level] = 1;
2767 c6c398c6 jim-p
				$current = &$current[$tag];
2768 23a193da Phil Davis
			} else {
2769
				if (isset ($current[$tag][0])) {
2770 86c707f3 Darren Embry
					$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
2771
					$repeated_tag_index[$tag . '_' . $level]++;
2772 23a193da Phil Davis
				} else {
2773 86c707f3 Darren Embry
					$current[$tag] = array (
2774
						$current[$tag],
2775
						$result
2776
						);
2777
					$repeated_tag_index[$tag . '_' . $level] = 2;
2778 23a193da Phil Davis
					if (isset ($current[$tag . '_attr'])) {
2779 86c707f3 Darren Embry
						$current[$tag]['0_attr'] = $current[$tag . '_attr'];
2780
						unset ($current[$tag . '_attr']);
2781
					}
2782
				}
2783
				$last_item_index = $repeated_tag_index[$tag . '_' . $level] - 1;
2784 c6c398c6 jim-p
				$current = &$current[$tag][$last_item_index];
2785 86c707f3 Darren Embry
			}
2786 23a193da Phil Davis
		} elseif ($type == "complete") {
2787
			if (!isset ($current[$tag])) {
2788 86c707f3 Darren Embry
				$current[$tag] = $result;
2789
				$repeated_tag_index[$tag . '_' . $level] = 1;
2790 23a193da Phil Davis
				if ($priority == 'tag' and $attributes_data) {
2791 86c707f3 Darren Embry
					$current[$tag . '_attr'] = $attributes_data;
2792 23a193da Phil Davis
				}
2793
			} else {
2794
				if (isset ($current[$tag][0]) and is_array($current[$tag])) {
2795 86c707f3 Darren Embry
					$current[$tag][$repeated_tag_index[$tag . '_' . $level]] = $result;
2796 23a193da Phil Davis
					if ($priority == 'tag' and $get_attributes and $attributes_data) {
2797 86c707f3 Darren Embry
						$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
2798
					}
2799
					$repeated_tag_index[$tag . '_' . $level]++;
2800 23a193da Phil Davis
				} else {
2801 86c707f3 Darren Embry
					$current[$tag] = array (
2802
						$current[$tag],
2803
						$result
2804
						);
2805
					$repeated_tag_index[$tag . '_' . $level] = 1;
2806 23a193da Phil Davis
					if ($priority == 'tag' and $get_attributes) {
2807
						if (isset ($current[$tag . '_attr'])) {
2808 86c707f3 Darren Embry
							$current[$tag]['0_attr'] = $current[$tag . '_attr'];
2809
							unset ($current[$tag . '_attr']);
2810
						}
2811 23a193da Phil Davis
						if ($attributes_data) {
2812 86c707f3 Darren Embry
							$current[$tag][$repeated_tag_index[$tag . '_' . $level] . '_attr'] = $attributes_data;
2813
						}
2814
					}
2815
					$repeated_tag_index[$tag . '_' . $level]++; //0 and 1 index is already taken
2816
				}
2817
			}
2818 23a193da Phil Davis
		} elseif ($type == 'close') {
2819 c6c398c6 jim-p
			$current = &$parent[$level -1];
2820 86c707f3 Darren Embry
		}
2821
	}
2822
	return ($xml_array);
2823 3ffa8318 Renato Botelho
}
2824
2825 d166b7e2 Renato Botelho
function get_country_name($country_code = "ALL") {
2826 23a193da Phil Davis
	if ($country_code != "ALL" && strlen($country_code) != 2) {
2827 3ffa8318 Renato Botelho
		return "";
2828 23a193da Phil Davis
	}
2829 3ffa8318 Renato Botelho
2830 cb0f6bf4 Renato Botelho
	$country_names_xml = "/usr/local/share/pfSense/iso_3166-1_list_en.xml";
2831 3ffa8318 Renato Botelho
	$country_names_contents = file_get_contents($country_names_xml);
2832
	$country_names = xml2array($country_names_contents);
2833
2834 23a193da Phil Davis
	if ($country_code == "ALL") {
2835 3ffa8318 Renato Botelho
		$country_list = array();
2836 23a193da Phil Davis
		foreach ($country_names['ISO_3166-1_List_en']['ISO_3166-1_Entry'] as $country) {
2837
			$country_list[] = array(
2838
				"code" => $country['ISO_3166-1_Alpha-2_Code_element'],
2839
				"name" => ucwords(strtolower($country['ISO_3166-1_Country_name'])));
2840 3ffa8318 Renato Botelho
		}
2841
		return $country_list;
2842
	}
2843
2844
	foreach ($country_names['ISO_3166-1_List_en']['ISO_3166-1_Entry'] as $country) {
2845
		if ($country['ISO_3166-1_Alpha-2_Code_element'] == strtoupper($country_code)) {
2846
			return ucwords(strtolower($country['ISO_3166-1_Country_name']));
2847
		}
2848
	}
2849
	return "";
2850
}
2851
2852 6a532672 Renato Botelho
/* Return the list of country codes to be used on CAs and certs */
2853
function get_cert_country_codes() {
2854
	$countries = get_country_name();
2855
2856
	$country_codes = array();
2857
	foreach ($countries as $country) {
2858
		$country_codes[$country['code']] = $country['code'];
2859
	}
2860 63cf3f32 Renato Botelho
	ksort($country_codes);
2861 6a532672 Renato Botelho
2862
	/* Preserve historical order: None, US, CA, other countries */
2863
	$first_items[''] = gettext("None");
2864
	$first_items['US'] = $country_codes['US'];
2865
	$first_items['CA'] = $country_codes['CA'];
2866
	unset($country_codes['US']);
2867
	unset($country_codes['CA']);
2868
2869
	return array_merge($first_items, $country_codes);
2870
}
2871
2872 baaa8bb1 Erik Fonnesbeck
/* sort by interface only, retain the original order of rules that apply to
2873
   the same interface */
2874
function filter_rules_sort() {
2875 67807c95 jim-p
	init_config_arr(array('filter', 'rule'));
2876 364c9484 Reid Linnemann
	$rules = config_get_path('filter/rule', []);
2877
2878 baaa8bb1 Erik Fonnesbeck
	/* mark each rule with the sequence number (to retain the order while sorting) */
2879 364c9484 Reid Linnemann
	for ($i = 0; isset($rules[$i]); $i++) {
2880
		$rules[$i]['seq'] =$i;
2881 23a193da Phil Davis
	}
2882 364c9484 Reid Linnemann
	usort($rules, "filter_rules_compare");
2883 baaa8bb1 Erik Fonnesbeck
2884
	/* strip the sequence numbers again */
2885 364c9484 Reid Linnemann
	for ($i = 0; isset($rules[$i]); $i++) {
2886
		unset($rules[$i]['seq']);
2887 23a193da Phil Davis
	}
2888 364c9484 Reid Linnemann
2889
	/* commit changes */
2890
	config_set_path('filter/rule', $rules);
2891 baaa8bb1 Erik Fonnesbeck
}
2892
function filter_rules_compare($a, $b) {
2893 23a193da Phil Davis
	if (isset($a['floating']) && isset($b['floating'])) {
2894 baaa8bb1 Erik Fonnesbeck
		return $a['seq'] - $b['seq'];
2895 23a193da Phil Davis
	} else if (isset($a['floating'])) {
2896 baaa8bb1 Erik Fonnesbeck
		return -1;
2897 23a193da Phil Davis
	} else if (isset($b['floating'])) {
2898 baaa8bb1 Erik Fonnesbeck
		return 1;
2899 23a193da Phil Davis
	} else if ($a['interface'] == $b['interface']) {
2900 cea355a5 Erik Fonnesbeck
		return $a['seq'] - $b['seq'];
2901 23a193da Phil Davis
	} else {
2902 baaa8bb1 Erik Fonnesbeck
		return compare_interface_friendly_names($a['interface'], $b['interface']);
2903 23a193da Phil Davis
	}
2904 baaa8bb1 Erik Fonnesbeck
}
2905
2906 22dae853 Seth Mos
function generate_ipv6_from_mac($mac) {
2907
	$elements = explode(":", $mac);
2908 23a193da Phil Davis
	if (count($elements) <> 6) {
2909 22dae853 Seth Mos
		return false;
2910 23a193da Phil Davis
	}
2911 22dae853 Seth Mos
2912
	$i = 0;
2913 5aa28c86 Seth Mos
	$ipv6 = "fe80::";
2914 23a193da Phil Davis
	foreach ($elements as $byte) {
2915
		if ($i == 0) {
2916 4de8f7ba Phil Davis
			$hexadecimal = substr($byte, 1, 2);
2917 22dae853 Seth Mos
			$bitmap = base_convert($hexadecimal, 16, 2);
2918
			$bitmap = str_pad($bitmap, 4, "0", STR_PAD_LEFT);
2919 4de8f7ba Phil Davis
			$bitmap = substr($bitmap, 0, 2) ."1". substr($bitmap, 3, 4);
2920 22dae853 Seth Mos
			$byte = substr($byte, 0, 1) . base_convert($bitmap, 2, 16);
2921
		}
2922
		$ipv6 .= $byte;
2923 23a193da Phil Davis
		if ($i == 1) {
2924 22dae853 Seth Mos
			$ipv6 .= ":";
2925
		}
2926 23a193da Phil Davis
		if ($i == 3) {
2927 22dae853 Seth Mos
			$ipv6 .= ":";
2928
		}
2929 23a193da Phil Davis
		if ($i == 2) {
2930 22dae853 Seth Mos
			$ipv6 .= "ff:fe";
2931
		}
2932 5fa78adc Renato Botelho
2933 22dae853 Seth Mos
		$i++;
2934 5fa78adc Renato Botelho
	}
2935 fcdc8943 Seth Mos
	return $ipv6;
2936 22dae853 Seth Mos
}
2937 325e3163 Bill Marquette
2938 57f2840e Evgeny
/****f* pfsense-utils/load_mac_manufacturer_table
2939
 * NAME
2940
 *   load_mac_manufacturer_table
2941
 * INPUTS
2942
 *   none
2943
 * RESULT
2944
 *   returns associative array with MAC-Manufacturer pairs
2945
 ******/
2946
function load_mac_manufacturer_table() {
2947
	/* load MAC-Manufacture data from the file */
2948 62a29fe3 Ermal
	$macs = false;
2949 23a193da Phil Davis
	if (file_exists("/usr/local/share/nmap/nmap-mac-prefixes")) {
2950 62a29fe3 Ermal
		$macs=file("/usr/local/share/nmap/nmap-mac-prefixes");
2951 23a193da Phil Davis
	}
2952
	if ($macs) {
2953
		foreach ($macs as $line) {
2954
			if (preg_match('/([0-9A-Fa-f]{6}) (.*)$/', $line, $matches)) {
2955 4450527f Evgeny
				/* store values like this $mac_man['000C29']='VMware' */
2956 4de8f7ba Phil Davis
				$mac_man["$matches[1]"] = $matches[2];
2957 57f2840e Evgeny
			}
2958
		}
2959 5fa78adc Renato Botelho
		return $mac_man;
2960 23a193da Phil Davis
	} else {
2961 57f2840e Evgeny
		return -1;
2962 23a193da Phil Davis
	}
2963 57f2840e Evgeny
2964
}
2965
2966 474f36d1 Scott Ullrich
/****f* pfsense-utils/is_ipaddr_configured
2967
 * NAME
2968
 *   is_ipaddr_configured
2969
 * INPUTS
2970
 *   IP Address to check.
2971 4665dbdd Renato Botelho
 *   If ignore_if is a VIP (not carp), vip array index is passed after string _virtualip
2972 f680e46c jim-p
 *   check_localip - if true then also check for matches with PPTP and L2TP addresses
2973 3490b8dd Phil Davis
 *   check_subnets - if true then check if the given ipaddr is contained anywhere in the subnet of any other configured IP address
2974
 *   cidrprefix - the CIDR prefix (16, 20, 24, 64...) of ipaddr.
2975 086cf944 Phil Davis
 *     If check_subnets is true and cidrprefix is specified,
2976 3490b8dd Phil Davis
 *     then check if the ipaddr/cidrprefix subnet overlaps the subnet of any other configured IP address
2977 474f36d1 Scott Ullrich
 * RESULT
2978 3490b8dd Phil Davis
 *   returns true if the IP Address is configured and present on this device or overlaps a configured subnet.
2979 474f36d1 Scott Ullrich
*/
2980 3490b8dd Phil Davis
function is_ipaddr_configured($ipaddr, $ignore_if = "", $check_localip = false, $check_subnets = false, $cidrprefix = "") {
2981
	if (count(where_is_ipaddr_configured($ipaddr, $ignore_if, $check_localip, $check_subnets, $cidrprefix))) {
2982
		return true;
2983
	}
2984
	return false;
2985
}
2986
2987
/****f* pfsense-utils/where_is_ipaddr_configured
2988
 * NAME
2989
 *   where_is_ipaddr_configured
2990
 * INPUTS
2991
 *   IP Address to check.
2992
 *   If ignore_if is a VIP (not carp), vip array index is passed after string _virtualip
2993 f680e46c jim-p
 *   check_localip - if true then also check for matches with PPTP and L2TP addresses
2994 3490b8dd Phil Davis
 *   check_subnets - if true then check if the given ipaddr is contained anywhere in the subnet of any other configured IP address
2995
 *   cidrprefix - the CIDR prefix (16, 20, 24, 64...) of ipaddr.
2996 086cf944 Phil Davis
 *     If check_subnets is true and cidrprefix is specified,
2997 3490b8dd Phil Davis
 *     then check if the ipaddr/cidrprefix subnet overlaps the subnet of any other configured IP address
2998
 * RESULT
2999
 *   Returns an array of the interfaces 'if' plus IP address or subnet 'ip_or_subnet' that match or overlap the IP address to check.
3000
 *   If there are no matches then an empty array is returned.
3001
*/
3002
function where_is_ipaddr_configured($ipaddr, $ignore_if = "", $check_localip = false, $check_subnets = false, $cidrprefix = "") {
3003
	$where_configured = array();
3004
3005 4665dbdd Renato Botelho
	$pos = strpos($ignore_if, '_virtualip');
3006
	if ($pos !== false) {
3007
		$ignore_vip_id = substr($ignore_if, $pos+10);
3008
		$ignore_vip_if = substr($ignore_if, 0, $pos);
3009
	} else {
3010
		$ignore_vip_id = -1;
3011
		$ignore_vip_if = $ignore_if;
3012
	}
3013
3014 1e5da31d Ermal
	$isipv6 = is_ipaddrv6($ipaddr);
3015
3016 cde28bfa Phil Davis
	if ($isipv6) {
3017
		$ipaddr = text_to_compressed_ip6($ipaddr);
3018
	}
3019
3020 e6c60013 Renato Botelho
	if ($check_subnets) {
3021 3490b8dd Phil Davis
		$cidrprefix = intval($cidrprefix);
3022
		if ($isipv6) {
3023
			if (($cidrprefix < 1) || ($cidrprefix > 128)) {
3024
				$cidrprefix = 128;
3025
			}
3026
		} else {
3027
			if (($cidrprefix < 1) || ($cidrprefix > 32)) {
3028
				$cidrprefix = 32;
3029
			}
3030
		}
3031 e6c60013 Renato Botelho
		$iflist = get_configured_interface_list();
3032
		foreach ($iflist as $if => $ifname) {
3033 23a193da Phil Davis
			if ($ignore_if == $if) {
3034 e6c60013 Renato Botelho
				continue;
3035 23a193da Phil Davis
			}
3036 2c98a935 Renato Botelho
3037 3490b8dd Phil Davis
			if ($isipv6) {
3038
				$if_ipv6 = get_interface_ipv6($if);
3039
				$if_snbitsv6 = get_interface_subnetv6($if);
3040 59724429 Viktor G
				/* do not check subnet overlapping on 6rd interfaces,
3041
				 * see https://redmine.pfsense.org/issues/12371 */ 
3042
				if ($if_ipv6 && $if_snbitsv6 &&
3043 364c9484 Reid Linnemann
				    ((config_get_path("interfaces/{$if}/ipaddrv6") != '6rd') || ($cidrprefix > $if_snbitsv6)) &&
3044 59724429 Viktor G
				    check_subnetsv6_overlap($ipaddr, $cidrprefix, $if_ipv6, $if_snbitsv6)) {
3045 3490b8dd Phil Davis
					$where_entry = array();
3046
					$where_entry['if'] = $if;
3047
					$where_entry['ip_or_subnet'] = get_interface_ipv6($if) . "/" . get_interface_subnetv6($if);
3048
					$where_configured[] = $where_entry;
3049
				}
3050 1e5da31d Ermal
			} else {
3051 3490b8dd Phil Davis
				$if_ipv4 = get_interface_ip($if);
3052
				$if_snbitsv4 = get_interface_subnet($if);
3053
				if ($if_ipv4 && $if_snbitsv4 && check_subnets_overlap($ipaddr, $cidrprefix, $if_ipv4, $if_snbitsv4)) {
3054
					$where_entry = array();
3055
					$where_entry['if'] = $if;
3056
					$where_entry['ip_or_subnet'] = get_interface_ip($if) . "/" . get_interface_subnet($if);
3057
					$where_configured[] = $where_entry;
3058 4de8f7ba Phil Davis
				}
3059 23a193da Phil Davis
			}
3060 e6c60013 Renato Botelho
		}
3061
	} else {
3062 3490b8dd Phil Davis
		if ($isipv6) {
3063 2c98a935 Renato Botelho
			$interface_list_ips = get_configured_ipv6_addresses();
3064 23a193da Phil Davis
		} else {
3065 2c98a935 Renato Botelho
			$interface_list_ips = get_configured_ip_addresses();
3066 23a193da Phil Davis
		}
3067 2c98a935 Renato Botelho
3068 23a193da Phil Davis
		foreach ($interface_list_ips as $if => $ilips) {
3069
			if ($ignore_if == $if) {
3070 e6c60013 Renato Botelho
				continue;
3071 23a193da Phil Davis
			}
3072
			if (strcasecmp($ipaddr, $ilips) == 0) {
3073 3490b8dd Phil Davis
				$where_entry = array();
3074
				$where_entry['if'] = $if;
3075
				$where_entry['ip_or_subnet'] = $ilips;
3076
				$where_configured[] = $where_entry;
3077 23a193da Phil Davis
			}
3078 e6c60013 Renato Botelho
		}
3079 5fa78adc Renato Botelho
	}
3080 a1613b62 Renato Botelho
3081 e6c60013 Renato Botelho
	if ($check_localip) {
3082 364c9484 Reid Linnemann
		if (strcasecmp($ipaddr, text_to_compressed_ip6(config_get_path('l2tp/localip', ""))) == 0) {
3083 3490b8dd Phil Davis
			$where_entry = array();
3084
			$where_entry['if'] = 'l2tp';
3085 364c9484 Reid Linnemann
			$where_entry['ip_or_subnet'] = config_get_path('l2tp/localip');
3086 3490b8dd Phil Davis
			$where_configured[] = $where_entry;
3087 23a193da Phil Davis
		}
3088 a1613b62 Renato Botelho
	}
3089
3090 3490b8dd Phil Davis
	return $where_configured;
3091 474f36d1 Scott Ullrich
}
3092
3093 e4a8ed97 Scott Ullrich
/****f* pfsense-utils/pfSense_handle_custom_code
3094
 * NAME
3095
 *   pfSense_handle_custom_code
3096
 * INPUTS
3097
 *   directory name to process
3098
 * RESULT
3099
 *   globs the directory and includes the files
3100
 */
3101 d65962a7 Scott Ullrich
function pfSense_handle_custom_code($src_dir) {
3102 5fa78adc Renato Botelho
	// Allow extending of the nat edit page and include custom input validation
3103 23a193da Phil Davis
	if (is_dir("$src_dir")) {
3104 3dbceb92 Scott Ullrich
		$cf = glob($src_dir . "/*.inc");
3105 23a193da Phil Davis
		foreach ($cf as $nf) {
3106
			if ($nf == "." || $nf == "..") {
3107 d65962a7 Scott Ullrich
				continue;
3108 23a193da Phil Davis
			}
3109 d65962a7 Scott Ullrich
			// Include the extra handler
3110 86573bb9 Phil Davis
			include_once("$nf");
3111 d65962a7 Scott Ullrich
		}
3112
	}
3113
}
3114
3115 ceecd29b Renato Botelho
function set_language() {
3116 364c9484 Reid Linnemann
	global $g;
3117 ceecd29b Renato Botelho
3118 364c9484 Reid Linnemann
	$lang = "";
3119
	if (!empty(config_get_path('system/language'))) {
3120
		$lang = config_get_path('system/language');
3121 2568e151 Christian McDonald
	} elseif (!empty(g_get('language'))) {
3122
		$lang = g_get('language');
3123 ceecd29b Renato Botelho
	}
3124
	$lang .= ".UTF-8";
3125
3126
	putenv("LANG={$lang}");
3127 53c25dec Renato Botelho
	setlocale(LC_ALL, $lang);
3128
	textdomain("pfSense");
3129
	bindtextdomain("pfSense", "/usr/local/share/locale");
3130
	bind_textdomain_codeset("pfSense", $lang);
3131 3e139f90 Vinicius Coque
}
3132
3133
function get_locale_list() {
3134
	$locales = array(
3135 b0572bad Renato Botelho
		"bs" => gettext("Bosnian"),
3136 48a6bb92 Steve Beaver
		"zh_CN" => gettext("Chinese"),
3137 3cf5ed75 Renato Botelho
		"zh_Hans_CN" => gettext("Chinese (Simplified, China)"),
3138 47254a66 Renato Botelho do Couto
		"zh_Hans_HK" => gettext("Chinese (Simplified, Hong Kong SAR China)"),
3139
		"zh_Hant_TW" => gettext("Chinese (Traditional, Taiwan)"),
3140 3cf5ed75 Renato Botelho
		"nl" => gettext("Dutch"),
3141 3e139f90 Vinicius Coque
		"en_US" => gettext("English"),
3142 2e6e11f4 Renato Botelho
		"fr" => gettext("French"),
3143 3cf5ed75 Renato Botelho
		"de_DE" => gettext("German (Germany)"),
3144 bdb3bb8b Renato Botelho do Couto
		"it" => gettext("Italian"),
3145 b6acaf76 Renato Botelho
		"ko" => gettext("Korean"),
3146 42190719 Renato Botelho
		"nb" => gettext("Norwegian Bokmål"),
3147 ea4f7b62 Renato Botelho
		"pl" => gettext("Polish"),
3148 48a6bb92 Steve Beaver
		"pt_PT" => gettext("Portuguese"),
3149 9b18dc1b Renato Botelho
		"pt_BR" => gettext("Portuguese (Brazil)"),
3150 a6f3daf0 Renato Botelho
		"ru" => gettext("Russian"),
3151 3cf5ed75 Renato Botelho
		"es" => gettext("Spanish"),
3152
		"es_AR" => gettext("Spanish (Argentina)"),
3153 3e139f90 Vinicius Coque
	);
3154 e402b079 Steve Beaver
3155
	// If the locales are sorted, the order changes depending on the language selected. If the user accidentally
3156
	// selects the wrong language, this makes it very difficult to guess the intended language. NOT sorting
3157 48a6bb92 Steve Beaver
	// allows the user to remember that English (say) is the seventh on the list and to get back to it more easily
3158 e402b079 Steve Beaver
3159
	//asort($locales);
3160
3161 3e139f90 Vinicius Coque
	return $locales;
3162
}
3163 20a7cb15 smos
3164
function return_hex_ipv4($ipv4) {
3165 23a193da Phil Davis
	if (!is_ipaddrv4($ipv4)) {
3166 20a7cb15 smos
		return(false);
3167 23a193da Phil Davis
	}
3168 5fa78adc Renato Botelho
3169 20a7cb15 smos
	/* we need the hex form of the interface IPv4 address */
3170
	$ip4arr = explode(".", $ipv4);
3171 733c6f89 Ermal
	return (sprintf("%02x%02x%02x%02x", $ip4arr[0], $ip4arr[1], $ip4arr[2], $ip4arr[3]));
3172 20a7cb15 smos
}
3173
3174
function convert_ipv6_to_128bit($ipv6) {
3175 23a193da Phil Davis
	if (!is_ipaddrv6($ipv6)) {
3176 20a7cb15 smos
		return(false);
3177 23a193da Phil Davis
	}
3178 20a7cb15 smos
3179
	$ip6arr = array();
3180
	$ip6prefix = Net_IPv6::uncompress($ipv6);
3181
	$ip6arr = explode(":", $ip6prefix);
3182
	/* binary presentation of the prefix for all 128 bits. */
3183
	$ip6prefixbin = "";
3184 23a193da Phil Davis
	foreach ($ip6arr as $element) {
3185 20a7cb15 smos
		$ip6prefixbin .= sprintf("%016b", hexdec($element));
3186
	}
3187
	return($ip6prefixbin);
3188
}
3189
3190
function convert_128bit_to_ipv6($ip6bin) {
3191 23a193da Phil Davis
	if (strlen($ip6bin) <> 128) {
3192 20a7cb15 smos
		return(false);
3193 23a193da Phil Davis
	}
3194 20a7cb15 smos
3195
	$ip6arr = array();
3196
	$ip6binarr = array();
3197
	$ip6binarr = str_split($ip6bin, 16);
3198 23a193da Phil Davis
	foreach ($ip6binarr as $binpart) {
3199 20a7cb15 smos
		$ip6arr[] = dechex(bindec($binpart));
3200 23a193da Phil Davis
	}
3201 587995fb Phil Davis
	$ip6addr = text_to_compressed_ip6(implode(":", $ip6arr));
3202 20a7cb15 smos
3203
	return($ip6addr);
3204
}
3205
3206 8b198c64 smos
3207
/* Returns the calculated bit length of the prefix delegation from the WAN interface */
3208
/* DHCP-PD is variable, calculate from the prefix-len on the WAN interface */
3209
/* 6rd is variable, calculate from 64 - (v6 prefixlen - (32 - v4 prefixlen)) */
3210
/* 6to4 is 16 bits, e.g. 65535 */
3211
function calculate_ipv6_delegation_length($if) {
3212 364c9484 Reid Linnemann
	$cfg = config_get_path("interfaces/{$if}");
3213
	if (!is_array($cfg)) {
3214 8b198c64 smos
		return false;
3215 23a193da Phil Davis
	}
3216 8b198c64 smos
3217 364c9484 Reid Linnemann
	switch ($cfg['ipaddrv6']) {
3218 8b198c64 smos
		case "6to4":
3219
			$pdlen = 16;
3220
			break;
3221
		case "6rd":
3222 364c9484 Reid Linnemann
			$rd6plen = explode("/", $cfg['prefix-6rd']);
3223
			$pdlen = (64 - ((int) $rd6plen[1] + (32 - (int) $cfg['prefix-6rd-v4plen'])));
3224 8b198c64 smos
			break;
3225
		case "dhcp6":
3226 364c9484 Reid Linnemann
			$pdlen = $cfg['dhcp6-ia-pd-len'];
3227 8b198c64 smos
			break;
3228
		default:
3229
			$pdlen = 0;
3230
			break;
3231
	}
3232
	return($pdlen);
3233
}
3234 d23e157a smos
3235 a3d07046 Renato Botelho
function merge_ipv6_delegated_prefix($prefix, $suffix, $len = 64) {
3236 02004e7a Viktor G
	/* convert zero-value prefix IPv6 addresses with IPv4 mapping to hex
3237
	 * see https://redmine.pfsense.org/issues/12440 */
3238
	$suffix_list = explode(':', $suffix);
3239
	if (is_ipaddrv4($suffix_list[count($suffix_list) - 1])) {
3240
		$hexsuffix = dechex(ip2long($suffix_list[count($suffix_list) - 1]));
3241
		$suffix_list[count($suffix_list) - 1] = substr($hexsuffix, 0, 4);
3242
		$suffix_list[] = substr($hexsuffix, 4, 8);
3243
		$suffix = implode(':', $suffix_list);
3244
	}	
3245 a3d07046 Renato Botelho
	$prefix = Net_IPv6::uncompress($prefix, true);
3246
	$suffix = Net_IPv6::uncompress($suffix, true);
3247
3248
	/*
3249
	 * xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx:xxxx
3250
	 *                ^^^^ ^
3251
	 *                |||| \-> 64
3252
	 *                |||\---> 63, 62, 61, 60
3253
	 *                ||\----> 56
3254
	 *                |\-----> 52
3255
	 *                \------> 48
3256
	 */
3257
3258
	switch ($len) {
3259
	case 48:
3260
		$prefix_len = 15;
3261
		break;
3262
	case 52:
3263
		$prefix_len = 16;
3264
		break;
3265
	case 56:
3266
		$prefix_len = 17;
3267
		break;
3268 231fe954 Phil Davis
	case 59:
3269 a3d07046 Renato Botelho
	case 60:
3270
		$prefix_len = 18;
3271
		break;
3272
	/*
3273
	 * XXX 63, 62 and 61 should use 18 but PD can change and if
3274
	 * we let user chose this bit it can end up out of PD network
3275
	 *
3276
	 * Leave this with 20 for now until we find a way to let user
3277
	 * chose it. The side-effect is users with PD with one of these
3278
	 * lengths will not be able to setup DHCP server range for full
3279
	 * PD size, only for last /64 network
3280
	 */
3281
	case 63:
3282
	case 62:
3283
	case 61:
3284
	default:
3285
		$prefix_len = 20;
3286
		break;
3287
	}
3288
3289 587995fb Phil Davis
	return text_to_compressed_ip6(substr($prefix, 0, $prefix_len) .
3290 a3d07046 Renato Botelho
	    substr($suffix, $prefix_len));
3291 2bf455ca Renato Botelho
}
3292
3293 6c8beed3 Renato Botelho
function dhcpv6_pd_str_help($pdlen) {
3294
	$result = '';
3295
3296
	switch ($pdlen) {
3297
	case 48:
3298
		$result = '::xxxx:xxxx:xxxx:xxxx:xxxx';
3299
		break;
3300
	case 52:
3301
		$result = '::xxx:xxxx:xxxx:xxxx:xxxx';
3302
		break;
3303
	case 56:
3304
		$result = '::xx:xxxx:xxxx:xxxx:xxxx';
3305
		break;
3306 231fe954 Phil Davis
	case 59:
3307 6c8beed3 Renato Botelho
	case 60:
3308
		$result = '::x:xxxx:xxxx:xxxx:xxxx';
3309
		break;
3310
	/*
3311 b7908243 Phil Davis
	 * XXX 63, 62 and 61 should use same mask as 60 but if
3312
	 * we let the user choose this bit it can end up out of PD network
3313 6c8beed3 Renato Botelho
	 *
3314 b7908243 Phil Davis
	 * Leave this with the same as 64 for now until we find a way to
3315
	 * let the user choose it. The side-effect is users with PD with one
3316
	 * of these lengths will not be able to setup DHCP server ranges
3317 6c8beed3 Renato Botelho
	 * for full PD size, only for last /64 network
3318
	 */
3319
	case 61:
3320
	case 62:
3321
	case 63:
3322
	case 64:
3323 b7908243 Phil Davis
	default:
3324 6c8beed3 Renato Botelho
		$result = '::xxxx:xxxx:xxxx:xxxx';
3325
		break;
3326
	}
3327
3328
	return $result;
3329
}
3330
3331 d23e157a smos
function huawei_rssi_to_string($rssi) {
3332
	$dbm = array();
3333
	$i = 0;
3334 145cc518 smos
	$dbstart = -113;
3335 23a193da Phil Davis
	while ($i < 32) {
3336 145cc518 smos
		$dbm[$i] = $dbstart + ($i * 2);
3337 d23e157a smos
		$i++;
3338
	}
3339
	$percent = round(($rssi / 31) * 100);
3340 145cc518 smos
	$string = "rssi:{$rssi} level:{$dbm[$rssi]}dBm percent:{$percent}%";
3341 d23e157a smos
	return $string;
3342
}
3343
3344
function huawei_mode_to_string($mode, $submode) {
3345 e8c516a0 Phil Davis
	$modes[0] = gettext("None");
3346 5fa78adc Renato Botelho
	$modes[1] = "AMPS";
3347 d23e157a smos
	$modes[2] = "CDMA";
3348
	$modes[3] = "GSM/GPRS";
3349
	$modes[4] = "HDR";
3350
	$modes[5] = "WCDMA";
3351 5fa78adc Renato Botelho
	$modes[6] = "GPS";
3352 d23e157a smos
3353 e8c516a0 Phil Davis
	$submodes[0] = gettext("No Service");
3354 d23e157a smos
	$submodes[1] = "GSM";
3355
	$submodes[2] = "GPRS";
3356
	$submodes[3] = "EDGE";
3357
	$submodes[4] = "WCDMA";
3358
	$submodes[5] = "HSDPA";
3359
	$submodes[6] = "HSUPA";
3360 e313da37 smos
	$submodes[7] = "HSDPA+HSUPA";
3361 d23e157a smos
	$submodes[8] = "TD-SCDMA";
3362
	$submodes[9] = "HSPA+";
3363 e8c516a0 Phil Davis
	$string = "{$modes[$mode]}, {$submodes[$submode]} " . gettext("Mode");
3364 d23e157a smos
	return $string;
3365
}
3366
3367
function huawei_service_to_string($state) {
3368 e8c516a0 Phil Davis
	$modes[0] = gettext("No Service");
3369
	$modes[1] = gettext("Restricted Service");
3370
	$modes[2] = gettext("Valid Service");
3371
	$modes[3] = gettext("Restricted Regional Service");
3372
	$modes[4] = gettext("Powersaving Service");
3373 c6c55ee7 doktornotor
	$modes[255] = gettext("Unknown Service");
3374 e8c516a0 Phil Davis
	$string = $modes[$state];
3375 d23e157a smos
	return $string;
3376
}
3377
3378
function huawei_simstate_to_string($state) {
3379 e8c516a0 Phil Davis
	$modes[0] = gettext("Invalid SIM/locked State");
3380
	$modes[1] = gettext("Valid SIM State");
3381
	$modes[2] = gettext("Invalid SIM CS State");
3382
	$modes[3] = gettext("Invalid SIM PS State");
3383
	$modes[4] = gettext("Invalid SIM CS/PS State");
3384
	$modes[255] = gettext("Missing SIM State");
3385
	$string = $modes[$state];
3386 d23e157a smos
	return $string;
3387
}
3388 4adf752c smos
3389
function zte_rssi_to_string($rssi) {
3390
	return huawei_rssi_to_string($rssi);
3391
}
3392
3393
function zte_mode_to_string($mode, $submode) {
3394 e8c516a0 Phil Davis
	$modes[0] = gettext("No Service");
3395
	$modes[1] = gettext("Limited Service");
3396 4adf752c smos
	$modes[2] = "GPRS";
3397
	$modes[3] = "GSM";
3398
	$modes[4] = "UMTS";
3399
	$modes[5] = "EDGE";
3400 5fa78adc Renato Botelho
	$modes[6] = "HSDPA";
3401 4adf752c smos
3402
	$submodes[0] = "CS_ONLY";
3403
	$submodes[1] = "PS_ONLY";
3404
	$submodes[2] = "CS_PS";
3405
	$submodes[3] = "CAMPED";
3406 e8c516a0 Phil Davis
	$string = "{$modes[$mode]}, {$submodes[$submode]} " . gettext("Mode");
3407 4adf752c smos
	return $string;
3408
}
3409
3410 e8c516a0 Phil Davis
function zte_service_to_string($service) {
3411
	$modes[0] = gettext("Initializing Service");
3412
	$modes[1] = gettext("Network Lock error Service");
3413
	$modes[2] = gettext("Network Locked Service");
3414
	$modes[3] = gettext("Unlocked or correct MCC/MNC Service");
3415
	$string = $modes[$service];
3416 4adf752c smos
	return $string;
3417
}
3418
3419
function zte_simstate_to_string($state) {
3420 e8c516a0 Phil Davis
	$modes[0] = gettext("No action State");
3421
	$modes[1] = gettext("Network lock State");
3422
	$modes[2] = gettext("(U)SIM card lock State");
3423
	$modes[3] = gettext("Network Lock and (U)SIM card Lock State");
3424
	$string = $modes[$state];
3425 4adf752c smos
	return $string;
3426
}
3427 e9ab2ddb smos
3428
function get_configured_pppoe_server_interfaces() {
3429
	$iflist = array();
3430 364c9484 Reid Linnemann
	foreach (config_get_path('pppoes/pppoe', []) as $pppoe) {
3431
		if ($pppoe['mode'] == "server") {
3432
			$int = "poes". $pppoe['pppoeid'];
3433
			$iflist[$int] = strtoupper($int);
3434 e9ab2ddb smos
		}
3435
	}
3436
	return $iflist;
3437
}
3438
3439
function get_pppoes_child_interfaces($ifpattern) {
3440
	$if_arr = array();
3441 23a193da Phil Davis
	if ($ifpattern == "") {
3442 e9ab2ddb smos
		return;
3443 23a193da Phil Davis
	}
3444 e9ab2ddb smos
3445 84c82d3d doktornotor
	exec("/sbin/ifconfig", $out, $ret);
3446 23a193da Phil Davis
	foreach ($out as $line) {
3447 50b84727 Viktor G
		if (preg_match("/^({$ifpattern}-[0-9]+):/i", $line, $match)) {
3448 e9ab2ddb smos
			$if_arr[] = $match[1];
3449
		}
3450
	}
3451
	return $if_arr;
3452
3453
}
3454
3455 331166a8 PiBa-NL
/****f* pfsense-utils/pkg_call_plugins
3456
 * NAME
3457
 *   pkg_call_plugins
3458
 * INPUTS
3459
 *   $plugin_type value used to search in package configuration if the plugin is used, also used to create the function name
3460
 *   $plugin_params parameters to pass to the plugin function for passing multiple parameters a array can be used.
3461
 * RESULT
3462
 *   returns associative array results from the plugin calls for each package
3463
 * NOTES
3464
 *   This generic function can be used to notify or retrieve results from functions that are defined in packages.
3465
 ******/
3466
function pkg_call_plugins($plugin_type, $plugin_params) {
3467 364c9484 Reid Linnemann
	global $g;
3468 eaee3af6 PiBa-NL
	$results = array();
3469 364c9484 Reid Linnemann
	foreach (config_get_path('installedpackages/package') as $package) {
3470 804fecdd PiBa-NL
		if (is_array($package['plugins']['item'])) {
3471
			foreach ($package['plugins']['item'] as $plugin) {
3472 331166a8 PiBa-NL
				if ($plugin['type'] == $plugin_type) {
3473 804fecdd PiBa-NL
					if (file_exists($package['include_file'])) {
3474
						require_once($package['include_file']);
3475 23a193da Phil Davis
					} else {
3476 eaee3af6 PiBa-NL
						continue;
3477 23a193da Phil Davis
					}
3478 804fecdd PiBa-NL
					$pkgname = substr(reverse_strrchr($package['configurationfile'], "."), 0, -1);
3479 eaee3af6 PiBa-NL
					$plugin_function = $pkgname . '_'. $plugin_type;
3480 c42117c1 PiBa-NL
					$results[$pkgname] = call_user_func($plugin_function, $plugin_params);
3481 eaee3af6 PiBa-NL
				}
3482
			}
3483 23a193da Phil Davis
		}
3484 eaee3af6 PiBa-NL
	}
3485
	return $results;
3486
}
3487
3488 f3997278 Steve Beaver
// Convert IPv6 addresses to lower case
3489
function addrtolower($ip) {
3490
	if (!filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6) === false) {
3491
		return(strtolower($ip));
3492
	} else {
3493
		return($ip);
3494
	}
3495
}
3496 2c1a08a8 jim-p
3497
function compare_by_name($a, $b) {
3498
	return strcasecmp($a['name'], $b['name']);
3499
}
3500 a436447f PiBa-NL
3501
/****f* pfsense-utils/getarraybyref
3502
 * NAME
3503
 *   getarraybyref
3504
 * INPUTS
3505 895708c5 Marco Pannetto
 *   $array the array of which a items array needs to be found.
3506 a436447f PiBa-NL
 *   $args.. the sub-items to be retrieved/created
3507
 * RESULT
3508
 *   returns the array that was retrieved from configuration, its created if it does not exist
3509
 * NOTES
3510 895708c5 Marco Pannetto
 *   Used by haproxy / acme / others.?. .
3511 a436447f PiBa-NL
 *   can be used like this:  $a_certificates = getarraybyref($config, 'installedpackages', 'acme', 'certificates', 'item');
3512
 ******/
3513
function &getarraybyref(&$array) {
3514
	if (!isset($array)) {
3515
		return false;
3516
	}
3517
	if (!is_array($array)) {
3518
		$array = array();
3519
	}
3520
	$item = &$array;
3521
	$arg = func_get_args();
3522
	for($i = 1; $i < count($arg); $i++) {
3523
		$itemindex = $arg[$i];
3524
		if (!is_array($item[$itemindex])) {
3525
			$item[$itemindex] = array();
3526
		}
3527
		$item = &$item[$itemindex];
3528
	}
3529
	return $item;
3530
}
3531
3532 1342f80f jim-p
/****f* pfsense-utils/send_download_data
3533
 * NAME
3534
 *   send_download_data - Send content to a user's browser as a file to download
3535
 * INPUTS
3536
 *   $type        : The type of download, either 'data' to send the contents of
3537
 *                    a variable or 'file' to send the contents of a file on the
3538
 *                    filesystem.
3539
 *   $content     : For 'data' type, the content to send the user. For 'file'
3540
 *                    type, the full path to the file to send.
3541
 *   $userfilename: The filename presented to the user when downloading. For
3542
 *                    'file' type, this may be omitted and the basename of
3543
 *                    $content will be used instead.
3544
 *   $contenttype : MIME content type of the data. Default "application/octet-stream"
3545
 * RESULT
3546
 *   Sends the data to the browser as a file to download.
3547
 ******/
3548
3549 de3f6463 Reid Linnemann
function send_user_download($type, $content, $userfilename = "", $contenttype = "application/octet-stream") {
3550 1342f80f jim-p
	/* If the type is 'file', then use the file size, otherwise use the size of the data to send */
3551
	$size = ($type == 'file') ? filesize($content) : strlen($content);
3552
3553
	/* If the filename to pass to the user is empty, assume it to be the filename being read. */
3554 ecb594d0 jim-p
	$name = basename((($type == 'file') && empty($userfilename)) ? $content : $userfilename);
3555 1342f80f jim-p
3556
	/* Cannot determine the filename, so bail. */
3557
	if (empty($name)) {
3558
		exit;
3559
	}
3560
3561
	/* Send basic download headers */
3562
	header("Content-Type: {$contenttype}");
3563
	header("Content-Length: {$size}");
3564
	header("Content-Disposition: attachment; filename=" . urlencode($name));
3565
3566
	/* Send cache headers */
3567
	if (isset($_SERVER['HTTPS'])) {
3568
		header('Pragma: ');
3569
		header('Cache-Control: ');
3570
	} else {
3571
		header("Pragma: private");
3572
		header("Cache-Control: private, must-revalidate");
3573
	}
3574
3575
	/* Ensure output buffering is off so PHP does not consume
3576
	 * memory in readfile(). https://redmine.pfsense.org/issues/9239 */
3577
	while (ob_get_level()) {
3578
		@ob_end_clean();
3579
	}
3580
3581
	/* Send the data to the user */
3582
	if ($type == 'file') {
3583
		readfile($content);
3584
	} else {
3585
		echo $content;
3586
	}
3587
3588
	/* Flush any remaining output buffer */
3589
	@ob_end_flush();
3590
	exit;
3591
}
3592
3593 3c07f498 Tom Embt
// Test whether the hostname in a URL can be resolved with a very short timeout
3594
function is_url_hostname_resolvable($url) {
3595 f5e8bd4d Tom Embt
	$urlhostname = parse_url($url, PHP_URL_HOST);
3596 e0479d47 Tom Embt
	if (empty($urlhostname)) {
3597
		return false;
3598
	}
3599 3c07f498 Tom Embt
	putenv("RES_OPTIONS=timeout:3 attempts:1");
3600 f5e8bd4d Tom Embt
	$resolvable = ($urlhostname !== gethostbyname($urlhostname));
3601 3c07f498 Tom Embt
	putenv("RES_OPTIONS");
3602
	return $resolvable;
3603
}
3604
3605 7e107c67 Viktor G
function get_pf_timeouts () {
3606
	$pftimeout = array();
3607
	exec("/sbin/pfctl -st", $pfctlst, $retval);
3608
	if ($retval == 0) {
3609 6728e5f4 Viktor G
		foreach ($pfctlst as $pfst) {
3610 7e107c67 Viktor G
			preg_match('/([a-z]+)\.([a-z]+)\s+([0-9]+)/', $pfst, $timeout);
3611
			if ($timeout[1] == "other") {
3612
				$proto = "Other";
3613
			} else {
3614
				$proto = strtoupper($timeout[1]);
3615
			}
3616
			if ($timeout[2] == "finwait") {
3617
				$type = "FIN Wait";
3618
			} else {
3619
				$type = ucfirst($timeout[2]);
3620
			}
3621
			$pftimeout[$proto][$type]['name'] = $proto . " " . $type;
3622
			$pftimeout[$proto][$type]['keyname'] = $timeout[1] . $timeout[2] . "timeout";
3623
			$pftimeout[$proto][$type]['value'] = $timeout[3];
3624
		}
3625
	}
3626
	return $pftimeout;
3627
}
3628
3629 8b424bca Viktor G
function set_curlproxy(&$ch) {
3630 364c9484 Reid Linnemann
	if (!empty(config_get_path('system/proxyurl'))) {
3631
		curl_setopt($ch, CURLOPT_PROXY, config_get_path('system/proxyurl'));
3632
		if (!empty(config_get_path('system/proxyport'))) {
3633
			curl_setopt($ch, CURLOPT_PROXYPORT, config_get_path('system/proxyport'));
3634
		}
3635
		$proxyuser = config_get_path('system/proxyuser');
3636
		$proxypass = config_get_path('system/proxypass');
3637
		if (!empty($proxyuser) && !empty($proxypass)) {
3638 8b424bca Viktor G
			@curl_setopt($ch, CURLOPT_PROXYAUTH, CURLAUTH_ANY | CURLAUTH_ANYSAFE);
3639 364c9484 Reid Linnemann
			curl_setopt($ch, CURLOPT_PROXYUSERPWD, "{$proxyuser}:{$proxypass}");
3640 8b424bca Viktor G
		}
3641
	}
3642
}
3643 58005e52 jim-p
?>