Project

General

Profile

« Previous | Next » 

Revision 4f3fc80d

Added by Renato Botelho over 8 years ago

Fix style

View differences:

src/etc/inc/util.inc
485 485
	return $rangeaddresses;
486 486
}
487 487

  
488
/* 	Convert an IPv4 or IPv6 IP range to an array of subnets which can contain the range.
489
	Algorithm and embodying code PD'ed by Stilez - enjoy as you like :-)
490

  
491
	Documented on pfsense dev list 19-20 May 2013. Summary:
492

  
493
	The algorithm looks at patterns of 0's and 1's in the least significant bit(s), whether IPv4 or IPv6.
494
	These are all that needs checking to identify a _guaranteed_ correct, minimal and optimal subnet array.
495

  
496
	As a result, string/binary pattern matching of the binary IP is very efficient. It uses just 2 pattern-matching rules
497
	to chop off increasingly larger subnets at both ends that can't be part of larger subnets, until nothing's left.
498

  
499
	(a) If any range has EITHER low bit 1 (in startip) or 0 (in endip), that end-point is _always guaranteed_ to be optimally
500
	represented by its own 'single IP' CIDR; the remaining range then shrinks by one IP up or down, causing the new end-point's
501
	low bit to change from 1->0 (startip) or 0->1 (endip). Only one edge case needs checking: if a range contains exactly 2
502
	adjacent IPs of this format, then the two IPs themselves are required to span it, and we're done.
503
	Once this rule is applied, the remaining range is _guaranteed_ to end in 0's and 1's so rule (b) can now be used, and its
504
	low bits can now be ignored.
505

  
506
	(b) If any range has BOTH startip and endip ending in some number of 0's and 1's respectively, these low bits can
507
	*always* be ignored and "bit-shifted" for subnet spanning. So provided we remember the bits we've place-shifted, we can
508
	_always_ right-shift and chop off those bits, leaving a smaller range that has EITHER startip ending in 1 or endip ending
509
	in 0 (ie can now apply (a) again) or the entire range has vanished and we're done.
510
	We then loop to redo (a) again on the remaining (place shifted) range until after a few loops, the remaining (place shifted)
511
	range 'vanishes' by meeting the exit criteria of (a) or (b), and we're done.
512
*/
513

  
488
/*
489
 * Convert an IPv4 or IPv6 IP range to an array of subnets which can contain the range.
490
 * Algorithm and embodying code PD'ed by Stilez - enjoy as you like :-)
491
 *
492
 * Documented on pfsense dev list 19-20 May 2013. Summary:
493
 *
494
 * The algorithm looks at patterns of 0's and 1's in the least significant bit(s), whether IPv4 or IPv6.
495
 * These are all that needs checking to identify a _guaranteed_ correct, minimal and optimal subnet array.
496
 *
497
 * As a result, string/binary pattern matching of the binary IP is very efficient. It uses just 2 pattern-matching rules
498
 * to chop off increasingly larger subnets at both ends that can't be part of larger subnets, until nothing's left.
499
 *
500
 * (a) If any range has EITHER low bit 1 (in startip) or 0 (in endip), that end-point is _always guaranteed_ to be optimally
501
 * represented by its own 'single IP' CIDR; the remaining range then shrinks by one IP up or down, causing the new end-point's
502
 * low bit to change from 1->0 (startip) or 0->1 (endip). Only one edge case needs checking: if a range contains exactly 2
503
 * adjacent IPs of this format, then the two IPs themselves are required to span it, and we're done.
504
 * Once this rule is applied, the remaining range is _guaranteed_ to end in 0's and 1's so rule (b) can now be used, and its
505
 * low bits can now be ignored.
506
 *
507
 * (b) If any range has BOTH startip and endip ending in some number of 0's and 1's respectively, these low bits can
508
 * *always* be ignored and "bit-shifted" for subnet spanning. So provided we remember the bits we've place-shifted, we can
509
 * _always_ right-shift and chop off those bits, leaving a smaller range that has EITHER startip ending in 1 or endip ending
510
 * in 0 (ie can now apply (a) again) or the entire range has vanished and we're done.
511
 * We then loop to redo (a) again on the remaining (place shifted) range until after a few loops, the remaining (place shifted)
512
 * range 'vanishes' by meeting the exit criteria of (a) or (b), and we're done.
513
 */
514 514
function ip_range_to_subnet_array($ip1, $ip2) {
515 515

  
516 516
	if (is_ipaddrv4($ip1) && is_ipaddrv4($ip2)) {
......
1790 1790

  
1791 1791
/* return a fieldname that is safe for xml usage */
1792 1792
function xml_safe_fieldname($fieldname) {
1793
	$replace = array('/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
1794
			 '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
1795
			 ':', ',', '.', '\'', '\\'
1796
		);
1793
	$replace = array(
1794
	    '/', '-', ' ', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')',
1795
	    '_', '+', '=', '{', '}', '[', ']', '|', '/', '<', '>', '?',
1796
	    ':', ',', '.', '\'', '\\'
1797
	);
1797 1798
	return strtolower(str_replace($replace, "", $fieldname));
1798 1799
}
1799 1800

  
......
2572 2573
	}
2573 2574

  
2574 2575
	array_walk($values, function(&$value) {
2575
		$value = str_pad($value, 2, '0', STR_PAD_LEFT); 
2576
		$value = str_pad($value, 2, '0', STR_PAD_LEFT);
2576 2577
	});
2577 2578

  
2578 2579
	return implode(":", $values);
......
2597 2598
function write_dhcp6_duid($duidstring) {
2598 2599
	// Create the hex array from the dhcp6duid config entry and write to file
2599 2600
	global $g;
2600
 	
2601
 	if(!is_duid($duidstring)) {
2601

  
2602
	if(!is_duid($duidstring)) {
2602 2603
		log_error(gettext("Error: attempting to write DUID file - Invalid DUID detected"));
2603 2604
		return false;
2604 2605
	}
......
2614 2615
}
2615 2616

  
2616 2617
/* returns duid string from 'vardb_path']}/dhcp6c_duid' */
2617
function get_duid_from_file()
2618
{
2618
function get_duid_from_file() {
2619 2619
	global $g;
2620
	
2620

  
2621 2621
	$duid_ASCII = "";
2622 2622
	$count = 0;
2623 2623
	
2624 2624
	if ($fd = fopen("{$g['vardb_path']}/dhcp6c_duid", "r")) {
2625 2625
		if(filesize("{$g['vardb_path']}/dhcp6c_duid")==16) {
2626
			$buffer = fread($fd,16);					
2626
			$buffer = fread($fd,16);
2627 2627
			while($count < 16) {
2628 2628
				$duid_ASCII .= bin2hex($buffer[$count]);
2629 2629
				$count++;
......
2638 2638
	if(!is_duid($duid_ASCII)) {
2639 2639
		return "--:--:--:--:--:--:--:--:--:--:--:--:--:--:--:--";
2640 2640
	}
2641
	return($duid_ASCII);	
2641
	return($duid_ASCII);
2642 2642
}
2643 2643
?>

Also available in: Unified diff