Revision 4f3fc80d
Added by Renato Botelho over 8 years ago
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
Fix style