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