diff options
Diffstat (limited to 'etc/inc')
-rw-r--r-- | etc/inc/auth.inc | 11 | ||||
-rw-r--r-- | etc/inc/authgui.inc | 16 | ||||
-rw-r--r-- | etc/inc/config.gui.inc | 1 | ||||
-rw-r--r-- | etc/inc/config.inc | 4 | ||||
-rw-r--r-- | etc/inc/easyrule.inc | 14 | ||||
-rw-r--r-- | etc/inc/filter.inc | 334 | ||||
-rw-r--r-- | etc/inc/filter_log.inc | 4 | ||||
-rw-r--r-- | etc/inc/globals.inc | 2 | ||||
-rw-r--r-- | etc/inc/gwlb.inc | 77 | ||||
-rw-r--r-- | etc/inc/interfaces.inc | 348 | ||||
-rw-r--r-- | etc/inc/ipsec.inc | 77 | ||||
-rw-r--r-- | etc/inc/openvpn.inc | 25 | ||||
-rw-r--r-- | etc/inc/pfsense-utils.inc | 106 | ||||
-rw-r--r-- | etc/inc/rrd.inc | 36 | ||||
-rw-r--r-- | etc/inc/services.inc | 512 | ||||
-rw-r--r-- | etc/inc/system.inc | 117 | ||||
-rw-r--r-- | etc/inc/upgrade_config.inc | 99 | ||||
-rw-r--r-- | etc/inc/util.inc | 81 | ||||
-rw-r--r-- | etc/inc/vpn.inc | 98 | ||||
-rw-r--r-- | etc/inc/xmlrpc_client.inc | 139 | ||||
-rw-r--r-- | etc/inc/xmlrpc_server.inc | 36 |
21 files changed, 1751 insertions, 386 deletions
diff --git a/etc/inc/auth.inc b/etc/inc/auth.inc index 239d7de..8dc0fe7 100644 --- a/etc/inc/auth.inc +++ b/etc/inc/auth.inc @@ -57,14 +57,21 @@ $security_passed = true; if (function_exists("display_error_form") && !isset($config['system']['webgui']['nodnsrebindcheck'])) { /* DNS ReBinding attack prevention. http://redmine.pfsense.org/issues/708 */ $found_host = false; + if(strstr($_SERVER['HTTP_HOST'], ":")) { $http_host_port = explode(":", $_SERVER['HTTP_HOST']); - $http_host = $http_host_port[0]; + /* v6 address has more parts, drop the last part */ + if(count($http_host_port) > 1) { + array_pop($http_host_port); + $http_host = str_replace(array("[", "]"), "", implode(":", $http_host_port)); + } else { + $http_host = $http_host_port[0]; + } } else { $http_host = $_SERVER['HTTP_HOST']; } if(is_ipaddr($http_host) or $_SERVER['SERVER_ADDR'] == "127.0.0.1" or - strcasecmp($http_host, "localhost") == 0) + strcasecmp($http_host, "localhost") == 0 or $_SERVER['SERVER_ADDR'] == "::1") $found_host = true; if(strcasecmp($http_host, $config['system']['hostname'] . "." . $config['system']['domain']) == 0 or strcasecmp($http_host, $config['system']['hostname']) == 0) diff --git a/etc/inc/authgui.inc b/etc/inc/authgui.inc index d64d1cc..070c0c2 100644 --- a/etc/inc/authgui.inc +++ b/etc/inc/authgui.inc @@ -178,14 +178,20 @@ if (empty($FilterIflist)) { require_once('shaper.inc'); filter_generate_optcfg_array(); } -foreach ($FilterIflist as $iflist) +foreach ($FilterIflist as $iflist) { if($iflist['ip'] == $http_host) $local_ip = true; -if($config['virtualip']) - if($config['virtualip']['vip']) - foreach($config['virtualip']['vip'] as $vip) + if($iflist['ipv6'] == $http_host) + $local_ip = true; +} +if($config['virtualip']) { + if($config['virtualip']['vip']) { + foreach($config['virtualip']['vip'] as $vip) { if($vip['subnet'] == $http_host) $local_ip = true; + } + } +} ?> <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" @@ -262,4 +268,4 @@ if($config['virtualip']) <?php } // end function -?>
\ No newline at end of file +?> diff --git a/etc/inc/config.gui.inc b/etc/inc/config.gui.inc index bfceb5a..0e00d44 100644 --- a/etc/inc/config.gui.inc +++ b/etc/inc/config.gui.inc @@ -54,6 +54,7 @@ else require_once('config.lib.inc'); require_once("notices.inc"); require_once("util.inc"); +require_once("IPv6.inc"); if(file_exists("/cf/conf/use_xmlreader")) require_once("xmlreader.inc"); else diff --git a/etc/inc/config.inc b/etc/inc/config.inc index 8a58d92..1485669 100644 --- a/etc/inc/config.inc +++ b/etc/inc/config.inc @@ -67,6 +67,8 @@ require_once('config.lib.inc'); if($g['booting']) echo "."; require_once("util.inc"); if($g['booting']) echo "."; +require_once("IPv6.inc"); +if($g['booting']) echo "."; if(file_exists("/cf/conf/use_xmlreader")) require_once("xmlreader.inc"); else @@ -218,4 +220,4 @@ if($config_parsed == true) { } } -?>
\ No newline at end of file +?> diff --git a/etc/inc/easyrule.inc b/etc/inc/easyrule.inc index 7b1c2b1..094bc83 100644 --- a/etc/inc/easyrule.inc +++ b/etc/inc/easyrule.inc @@ -46,7 +46,7 @@ function easyrule_find_rule_interface($int) { if ($config['pptpd']['mode'] == "server") $iflist['pptp'] = "PPTP VPN"; - if (is_pppoe_server_enabled() && have_ruleint_access("pppoe")) + if ($config['pppoe']['mode'] == "server") $iflist['pppoe'] = "PPPoE VPN"; if ($config['l2tp']['mode'] == "server") @@ -230,7 +230,7 @@ function easyrule_block_host_add($host, $int = 'wan') { } } -function easyrule_pass_rule_add($int, $proto, $srchost, $dsthost, $dstport) { +function easyrule_pass_rule_add($int, $proto, $srchost, $dsthost, $dstport, $ipproto) { global $config; /* No rules, start a new array */ @@ -245,6 +245,7 @@ function easyrule_pass_rule_add($int, $proto, $srchost, $dsthost, $dstport) { $filterent = array(); $filterent['type'] = 'pass'; $filterent['interface'] = $int; + $filterent['ipprotocol'] = $ipproto; $filterent['descr'] = "Easy Rule: Passed from Firewall Log View"; if ($proto != "any") @@ -272,7 +273,8 @@ function easyrule_pass_rule_add($int, $proto, $srchost, $dsthost, $dstport) { } } -function easyrule_parse_block($int, $src) { +function easyrule_parse_block($int, $src, $ipproto) { + $filterent['ipprotocol'] = $ipproto; if (!empty($src) && !empty($int)) { if (!is_ipaddr($src)) { return "Tried to block invalid IP: " . htmlspecialchars($src); @@ -291,7 +293,7 @@ function easyrule_parse_block($int, $src) { } return "Unknown block error."; } -function easyrule_parse_pass($int, $proto, $src, $dst, $dstport = 0) { +function easyrule_parse_pass($int, $proto, $src, $dst, $dstport = 0, $ipproto = inet) { /* Check for valid int, srchost, dsthost, dstport, and proto */ global $protocols_with_ports; @@ -320,7 +322,7 @@ function easyrule_parse_pass($int, $proto, $src, $dst, $dstport = 0) { $dstport = 0; } /* Should have valid input... */ - if (easyrule_pass_rule_add($int, $proto, $src, $dst, $dstport)) { + if (easyrule_pass_rule_add($int, $proto, $src, $dst, $dstport, $ipproto)) { return "Successfully added pass rule!"; } else { return "Failed to add pass rule."; @@ -331,4 +333,4 @@ function easyrule_parse_pass($int, $proto, $src, $dst, $dstport = 0) { return "Unknown pass error."; } -?>
\ No newline at end of file +?> diff --git a/etc/inc/filter.inc b/etc/inc/filter.inc index e5e173c..a949128 100644 --- a/etc/inc/filter.inc +++ b/etc/inc/filter.inc @@ -757,17 +757,21 @@ function filter_generate_optcfg_array() { if (!does_interface_exist($oic['if'])) continue; $oic['ip'] = get_interface_ip($if); + $oic['ipv6'] = get_interface_ipv6($if); if(!is_ipaddr($oc['ipaddr']) && !empty($oc['ipaddr'])) $oic['type'] = $oc['ipaddr']; $oic['sn'] = get_interface_subnet($if); + $oic['snv6'] = get_interface_subnetv6($if); $oic['mtu'] = empty($oc['mtu']) ? 1500 : $oc['mtu']; $oic['mss'] = empty($oc['mss']) ? '' : $oc['mss']; $oic['descr'] = $ifdetail; $oic['sa'] = gen_subnet($oic['ip'], $oic['sn']); + $oic['sav6'] = gen_subnetv6($oic['ipv6'], $oic['snv6']); $oic['nonat'] = $oc['nonat']; $oic['alias-address'] = $oc['alias-address']; $oic['alias-subnet'] = $oc['alias-subnet']; $oic['gateway'] = $oc['gateway']; + $oic['gatewayv6'] = $oc['gatewayv6']; $oic['spoofcheck'] = "yes"; $oic['bridge'] = link_interface_to_bridge($if); $FilterIflist[$if] = $oic; @@ -1269,6 +1273,35 @@ function filter_nat_rules_generate() { $reflection_txt .= filter_generate_reflection_nat($rule, $route_table, $nat_if_list, "", $srcaddr, $srcip, $sn); } } + + /* Add binat rules for Network Prefix translation */ + if(is_array($config['nat']['npt'])) { + foreach ($config['nat']['npt'] as $rule) { + if (isset($rule['disabled'])) + continue; + + if (!$rule['interface']) + $natif = "wan"; + else + $natif = $rule['interface']; + if (!isset($FilterIflist[$natif])) + continue; + + $srcaddr = filter_generate_address($rule, 'source'); + $dstaddr = filter_generate_address($rule, 'destination'); + + $srcaddr = trim($srcaddr); + $dstaddr = trim($dstaddr); + + $natif = $FilterIflist[$natif]['descr']; + + $natrules .= "binat on \${$natif} from {$srcaddr} to any -> {$dstaddr}\n"; + $natrules .= "binat on \${$natif} from any to {$dstaddr} -> {$srcaddr}\n"; + + } + } + + $natrules .= "\n# Outbound NAT rules\n"; /* outbound rules - advanced or standard */ if(isset($config['nat']['advancedoutbound']['enable'])) { @@ -1622,54 +1655,101 @@ function filter_generate_address(& $rule, $target = "source", $isnat = false) { if(strstr($rule[$target]['network'], "opt")) { $optmatch = ""; $matches = ""; - /* check for opt$NUMip here */ - if (preg_match("/opt([0-9]*)ip/", $rule[$target]['network'], $matches)) { - $src = $FilterIflist["opt{$matches[1]}"]['ip']; - if(!is_ipaddr($src)) - return ""; - } else if (preg_match("/opt([0-9]*)$/", $rule[$target]['network'], $optmatch)) { - $opt_ip = $FilterIflist["opt{$optmatch[1]}"]['ip']; - if(!is_ipaddr($opt_ip)) - return ""; - $src = $opt_ip . "/" . - $FilterIflist["opt{$optmatch[1]}"]['sn']; + if($rule['ipprotocol'] == "inet6") { + if(preg_match("/opt([0-9]*)$/", $rule[$target]['network'], $optmatch)) { + $opt_ip = $FilterIflist["opt{$optmatch[1]}"]['ipv6']; + if(!is_ipaddr($opt_ip)) + return ""; + $src = $opt_ip . "/" . + $FilterIflist["opt{$optmatch[1]}"]['snv6']; + /* check for opt$NUMip here */ + } else if(preg_match("/opt([0-9]*)ip/", $rule[$target]['network'], $matches)) { + $src = $FilterIflist["opt{$matches[1]}"]['ipv6']; + if(!is_ipaddr($src)) + return ""; + } + if(isset($rule[$target]['not'])) + $src = " !{$src}"; + } else { + if(preg_match("/opt([0-9]*)$/", $rule[$target]['network'], $optmatch)) { + $opt_ip = $FilterIflist["opt{$optmatch[1]}"]['ip']; + if(!is_ipaddr($opt_ip)) + return ""; + $src = $opt_ip . "/" . + $FilterIflist["opt{$optmatch[1]}"]['sn']; + /* check for opt$NUMip here */ + } else if(preg_match("/opt([0-9]*)ip/", $rule[$target]['network'], $matches)) { + $src = $FilterIflist["opt{$matches[1]}"]['ip']; + if(!is_ipaddr($src)) + return ""; + } + if(isset($rule[$target]['not'])) + $src = " !{$src}"; } - if(isset($rule[$target]['not'])) - $src = " !{$src}"; } else { - switch ($rule[$target]['network']) { - case 'wan': - $wansa = $FilterIflist['wan']['sa']; - $wansn = $FilterIflist['wan']['sn']; - $src = "{$wansa}/{$wansn}"; - break; - case 'wanip': - $src = $FilterIflist["wan"]['ip']; - break; - case 'lanip': - $src = $FilterIflist["lan"]['ip']; - break; - case 'lan': - $lansa = $FilterIflist['lan']['sa']; - $lansn = $FilterIflist['lan']['sn']; - $src = "{$lansa}/{$lansn}"; - break; - case 'pptp': - $pptpsa = gen_subnet($FilterIflist['pptp']['sa'], $FilterIflist['pptp']['sn']); - $pptpsn = $FilterIflist['pptp']['sn']; - $src = "{$pptpsa}/{$pptpsn}"; - break; - case 'pppoe': - /* XXX: This needs to be fixed somehow! */ - if (is_array($FilterIflist['pppoe'])) { - $pppoesa = gen_subnet($FilterIflist['pppoe'][0]['ip'], $FilterIflist['pppoe'][0]['sn']); - $pppoesn = $FilterIflist['pppoe'][0]['sn']; - $src = "{$pppoesa}/{$pppoesn}"; + if($rule['ipprotocol'] == "inet6") { + switch ($rule[$target]['network']) { + case 'wan': + $wansa = $FilterIflist['wan']['sav6']; + $wansn = $FilterIflist['wan']['snv6']; + $src = "{$wansa}/{$wansn}"; + break; + case 'wanip': + $src = $FilterIflist["wan"]['ipv6']; + break; + case 'lanip': + $src = $FilterIflist["lan"]['ipv6']; + break; + case 'lan': + $lansa = $FilterIflist['lan']['sav6']; + $lansn = $FilterIflist['lan']['snv6']; + $src = "{$lansa}/{$lansn}"; + break; + case 'pptp': + $pptpsav6 = gen_subnetv6($FilterIflist['pptp']['sav6'], $FilterIflist['pptp']['snv6']); + $pptpsnv6 = $FilterIflist['pptp']['snv6']; + $src = "{$pptpsav6}/{$pptpsnv6}"; + break; + case 'pppoe': + if (is_array($FilterIflist['pppoe'])) { + $pppoesav6 = gen_subnetv6($FilterIflist['pppoe'][0]['ipv6'], $FilterIflist['pppoe'][0]['snv6']); + $pppoesnv6 = $FilterIflist['pppoe'][0]['snv6']; + $src = "{$pppoesav6}/{$pppoesnv6}"; + } } - break; + } else { + switch ($rule[$target]['network']) { + case 'wan': + $wansa = $FilterIflist['wan']['sa']; + $wansn = $FilterIflist['wan']['sn']; + $src = "{$wansa}/{$wansn}"; + break; + case 'wanip': + $src = $FilterIflist["wan"]['ip']; + break; + case 'lanip': + $src = $FilterIflist["lan"]['ip']; + break; + case 'lan': + $lansa = $FilterIflist['lan']['sa']; + $lansn = $FilterIflist['lan']['sn']; + $src = "{$lansa}/{$lansn}"; + break; + case 'pptp': + $pptpsa = gen_subnet($FilterIflist['pptp']['ip'], $FilterIflist['pptp']['sn']); + $pptpsn = $FilterIflist['pptp']['sn']; + $src = "{$pptpsa}/{$pptpsn}"; + break; + case 'pppoe': + /* XXX: This needs to be fixed somehow! */ + if (is_array($FilterIflist['pppoe'])) { + $pppoesa = gen_subnet($FilterIflist['pppoe'][0]['ip'], $FilterIflist['pppoe'][0]['sn']); + $pppoesn = $FilterIflist['pppoe'][0]['sn']; + $src = "{$pppoesa}/{$pppoesn}"; + } + break; + } } - if(isset($rule[$target]['not'])) - $src = "!{$src}"; } } else if($rule[$target]['address']) { $expsrc = alias_expand($rule[$target]['address']); @@ -1754,6 +1834,17 @@ function filter_generate_user_rule($rule) { return "# source network or destination network == pptp on " . $rule['descr']; } + if(isset($rule['ipprotocol'])) { + switch($rule['ipprotocol']) { + case "inet": + $aline['ipprotocol'] = "inet"; + break; + case "inet6": + $aline['ipprotocol'] = "inet6"; + break; + } + } + /* check for unresolvable aliases */ if($rule['source']['address'] && !alias_expand($rule['source']['address'])) { file_notice("Filter_Reload", "# unresolvable source aliases {$rule['descr']}"); @@ -1790,12 +1881,23 @@ function filter_generate_user_rule($rule) { /* do not process reply-to for gateway'd rules */ if($rule['gateway'] == "" && $aline['direction'] <> "" && interface_has_gateway($rule['interface']) && !isset($config['system']['disablereplyto'])) { - $rg = get_interface_gateway($rule['interface']); - if(is_ipaddr($rg)) { - $aline['reply'] = "reply-to ( {$ifcfg['if']} {$rg} ) "; + if($rule['ipprotocol'] == "inet6") { + $rg = get_interface_gateway_v6($rule['interface']); + if(is_ipaddrv6($rg)) { + $aline['reply'] = "reply-to ( {$ifcfg['if']} {$rg} ) "; + } else { + if($rule['interface'] <> "pptp") { + log_error("Could not find IPv6 gateway for interface({$rule['interface']})."); + } + } } else { - if($rule['interface'] <> "pptp") { - log_error("Could not find gateway for interface({$rule['interface']})."); + $rg = get_interface_gateway($rule['interface']); + if(is_ipaddrv4($rg)) { + $aline['reply'] = "reply-to ( {$ifcfg['if']} {$rg} ) "; + } else { + if($rule['interface'] <> "pptp") { + log_error("Could not find IPv4 gateway for interface({$rule['interface']})."); + } } } } @@ -1811,8 +1913,10 @@ function filter_generate_user_rule($rule) { if (isset($rule['protocol']) && !empty($rule['protocol'])) { if($rule['protocol'] == "tcp/udp") $aline['prot'] = " proto { tcp udp } "; + elseif(($rule['protocol'] == "icmp") && ($rule['ipprotocol'] == "inet6")) + $aline['prot'] = " proto ipv6-icmp "; elseif($rule['protocol'] == "icmp") - $aline['prot'] = " inet proto icmp "; + $aline['prot'] = " proto icmp "; else $aline['prot'] = " proto {$rule['protocol']} "; } else { @@ -1848,8 +1952,10 @@ function filter_generate_user_rule($rule) { $l7_structures = $l7rule->get_unique_structures(); $aline['divert'] = "divert " . $l7rule->GetRPort() . " "; } - if(($rule['protocol'] == "icmp") && $rule['icmptype']) + if(($rule['protocol'] == "icmp") && $rule['icmptype'] && ($rule['ipprotocol'] == "inet")) $aline['icmp-type'] = "icmp-type {$rule['icmptype']} "; + if(($rule['protocol'] == "icmp") && $rule['icmptype'] && ($rule['ipprotocol'] == "inet6")) + $aline['icmp6-type'] = "icmp6-type {$rule['icmptype']} "; if(!empty($rule['tag'])) $aline['tag'] = " tag " .$rule['tag']. " "; if(!empty($rule['tagged'])) @@ -2006,8 +2112,8 @@ function filter_generate_user_rule($rule) { /* negate VPN/PPTP/PPPoE networks for load balancer/gateway rules */ $vpns = " to <vpns> "; $line .= $aline['type'] . $aline['direction'] . $aline['log'] . $aline['quick'] . - $aline['interface'] . $aline['prot'] . $aline['src'] . $aline['os'] . - $vpns . $aline['icmp-type'] . $aline['tag'] . $aline['tagged'] . + $aline['interface'] . $aline['ipprotocol'] . $aline['prot'] . $aline['src'] . $aline['os'] . + $vpns . $aline['icmp-type'] . $aline['icmp6-type'] . $aline['tag'] . $aline['tagged'] . $aline['dscp'] . $aline['allowopts'] . $aline['flags'] . $aline['queue'] . $aline['dnpipe'] . $aline['schedlabel'] . " label \"NEGATE_ROUTE: Negate policy route for vpn(s)\"\n"; @@ -2015,8 +2121,8 @@ function filter_generate_user_rule($rule) { } /* piece together the actual user rule */ $line .= $aline['type'] . $aline['direction'] . $aline['log'] . $aline['quick'] . $aline['interface'] . - $aline['reply'] . $aline['route'] . $aline['prot'] . $aline['src'] . $aline['os'] . $aline['dst'] . - $aline['divert'] . $aline['icmp-type'] . $aline['tag'] . $aline['tagged'] . $aline['dscp'] . + $aline['reply'] . $aline['route'] . $aline['ipprotocol'] . $aline['prot'] . $aline['src'] . $aline['os'] . $aline['dst'] . + $aline['divert'] . $aline['icmp-type'] . $aline['icmp6-type'] . $aline['tag'] . $aline['tagged'] . $aline['dscp'] . $aline['allowopts'] . $aline['flags'] . $aline['queue'] . $aline['dnpipe'] . $aline['schedlabel']; @@ -2049,20 +2155,43 @@ function filter_rules_generate() { #--------------------------------------------------------------------------- # default deny rules #--------------------------------------------------------------------------- -block in $log all label "Default deny rule" -block out $log all label "Default deny rule" +block in $log inet all label "Default deny rule IPv4" +block out $log inet all label "Default deny rule IPv4" +block in $log inet6 all label "Default deny rule IPv6" +block out $log inet6 all label "Default deny rule IPv6" + +# IPv6 ICMP is not auxilary, it is required for operation +# See man icmp6(4) +# 1 unreach Destination unreachable +# 2 toobig Packet too big +# 128 echoreq Echo service request +# 129 echorep Echo service reply +# 133 routersol Router solicitation +# 134 routeradv Router advertisement +# 135 neighbrsol Neighbor solicitation +# 136 neighbradv Neighbor advertisement +pass quick inet6 proto ipv6-icmp from any to any icmp6-type {1,2,135,136} keep state + +# Allow only bare essential icmpv6 packets (NS, NA, and RA, echoreq, echorep) +pass out quick inet6 proto ipv6-icmp from fe80::/10 to fe80::/10 icmp6-type {128,133,134,135,136} keep state +pass out quick inet6 proto ipv6-icmp from fe80::/10 to ff02::/16 icmp6-type {128,133,134,135,136} keep state +pass in quick inet6 proto ipv6-icmp from fe80::/10 to fe80::/10 icmp6-type {129,133,134,135,136} keep state +pass in quick inet6 proto ipv6-icmp from ff02::/16 to fe80::/10 icmp6-type {129,133,134,135,136} keep state +pass in quick inet6 proto ipv6-icmp from fe80::/10 to ff02::/16 icmp6-type {129,133,134,135,136} keep state # We use the mighty pf, we cannot be fooled. -block quick proto { tcp, udp } from any port = 0 to any -block quick proto { tcp, udp } from any to any port = 0 +block quick inet proto { tcp, udp } from any port = 0 to any +block quick inet proto { tcp, udp } from any to any port = 0 +block quick inet6 proto { tcp, udp } from any port = 0 to any +block quick inet6 proto { tcp, udp } from any to any port = 0 EOD; if(!isset($config['system']['ipv6allow'])) { $ipfrules .= "# Block all IPv6\n"; - $ipfrules .= "block in quick inet6 all\n"; - $ipfrules .= "block out quick inet6 all\n"; + $ipfrules .= "block in inet6 all label \"Default Deny ipv6 rule\"\n"; + $ipfrules .= "block out inet6 all label \"Default Deny ipv6 rule\"\n"; } $ipfrules .= <<<EOD @@ -2154,10 +2283,13 @@ EOD; if(isset($config['interfaces'][$on]['blockbogons'])) { if($bogontableinstalled == 0) $ipfrules .= "table <bogons> persist file \"/etc/bogons\"\n"; + $ipfrules .= "table <bogonsv6> persist file \"/etc/bogonsv6\"\n"; $ipfrules .= <<<EOD # block bogon networks # http://www.cymru.com/Documents/bogon-bn-nonagg.txt -block in $log quick on \${$oc['descr']} from <bogons> to any label "block bogon networks from {$oc['descr']}" +# http://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt +block in $log quick on \${$oc['descr']} from <bogons> to any label "block bogon IPv4 networks from {$oc['descr']}" +block in $log quick on \${$oc['descr']} from <bogonsv6> to any label "block bogon IPv6 networks from {$oc['descr']}" EOD; $bogontableinstalled++; @@ -2179,10 +2311,11 @@ EOD; $ipfrules .= <<<EOD # block anything from private networks on interfaces with the option set antispoof for \${$oc['descr']} -block in $log quick on \${$oc['descr']} from 10.0.0.0/8 to any label "block private networks from wan block 10/8" -block in $log quick on \${$oc['descr']} from 127.0.0.0/8 to any label "block private networks from wan block 127/8" -block in $log quick on \${$oc['descr']} from 172.16.0.0/12 to any label "block private networks from wan block 172.16/12" -block in $log quick on \${$oc['descr']} from 192.168.0.0/16 to any label "block private networks from wan block 192.168/16" +block in $log quick on \${$oc['descr']} from 10.0.0.0/8 to any label "Block private networks from {$oc['descr']} block 10/8" +block in $log quick on \${$oc['descr']} from 127.0.0.0/8 to any label "Block private networks from {$oc['descr']} block 127/8" +block in $log quick on \${$oc['descr']} from 172.16.0.0/12 to any label "Block private networks from {$oc['descr']} block 172.16/12" +block in $log quick on \${$oc['descr']} from 192.168.0.0/16 to any label "Block private networks from {$oc['descr']} block 192.168/16" +block in $log quick on \${$oc['descr']} from fc00::/7 to any label "Block ULA networks from {$oc['descr']} block fc00::/7" EOD; } @@ -2202,6 +2335,9 @@ EOD; # allow our DHCP client out to the {$oc['descr']} pass in on \${$oc['descr']} proto udp from any port = 67 to any port = 68 label "allow dhcp client out {$oc['descr']}" pass out on \${$oc['descr']} proto udp from any port = 68 to any port = 67 label "allow dhcp client out {$oc['descr']}" +# allow our DHCPv6 client out to the {$oc['descr']} +pass in on \${$oc['descr']} proto udp from any port = 547 to any port = 546 label "allow dhcpv6 client out {$oc['descr']}" +pass out on \${$oc['descr']} proto udp from any port = 546 to any port = 547 label "allow dhcpv6 client out {$oc['descr']}" # Not installing DHCP server firewall rules for {$oc['descr']} which is configured for DHCP. EOD; @@ -2215,6 +2351,7 @@ EOD; /* allow access to DHCP server on interfaces */ if(isset($config['dhcpd'][$on]['enable'])) { $ipfrules .= <<<EOD + # allow access to DHCP server on {$oc['descr']} pass in on \${$oc['descr']} proto udp from any port = 68 to 255.255.255.255 port = 67 label "allow access to DHCP server" pass in on \${$oc['descr']} proto udp from any port = 68 to {$oc['ip']} port = 67 label "allow access to DHCP server" @@ -2231,6 +2368,19 @@ EOD; } } + if(isset($config['dhcpdv6'][$on]['enable'])) { + $ipfrules .= <<<EOD + +# allow access to DHCPv6 server on {$oc['descr']} +anchor "dhcpv6server{$oc['descr']}" +# We need inet6 icmp for stateless autoconfig and dhcpv6 +pass in on \${$oc['descr']} inet6 proto udp from fe80::/10 to ff02::/16 port = 546 label "allow access to DHCPv6 server" +pass in on \${$oc['descr']} inet6 proto udp from fe80::/10 to ff02::/16 port = 547 label "allow access to DHCPv6 server" +pass in on \${$oc['descr']} inet6 proto udp from fe80::/10 to {$oc['ipv6']} port = 546 label "allow access to DHCPv6 server" +pass out on \${$oc['descr']} inet6 proto udp from {$oc['ipv6']} port = 547 to fe80::/10 label "allow access to DHCPv6 server" + +EOD; + } break; } } @@ -2242,24 +2392,32 @@ EOD; $ipfrules .= <<<EOD # loopback -pass in on \$loopback all label "pass loopback" -pass out on \$loopback all label "pass loopback" +pass in on \$loopback inet all label "pass IPv4 loopback" +pass out on \$loopback inet all label "pass IPv4 loopback" +pass in on \$loopback inet6 all label "pass IPv6 loopback" +pass out on \$loopback inet6 all label "pass IPv6 loopback" EOD; $ipfrules .= <<<EOD # let out anything from the firewall host itself and decrypted IPsec traffic -pass out all keep state allow-opts label "let out anything from firewall host itself" +pass out inet all keep state allow-opts label "let out anything IPv4 from firewall host itself" +pass out inet6 all keep state allow-opts label "let out anything IPv6 from firewall host itself" EOD; foreach ($FilterIflist as $ifdescr => $ifcfg) { - if(isset($ifcfg['virtual'])) - continue; + if(isset($ifcfg['virtual'])) + continue; + $gw = get_interface_gateway($ifdescr); if (is_ipaddr($gw) && is_ipaddr($ifcfg['ip'])) $ipfrules .= "pass out route-to ( {$ifcfg['if']} {$gw} ) from {$ifcfg['ip']} to !{$ifcfg['sa']}/{$ifcfg['sn']} keep state allow-opts label \"let out anything from firewall host itself\"\n"; - } + $gwv6 = get_interface_gateway_v6($ifdescr); + if (is_ipaddrv6($gwv6) && is_ipaddrv6($ifcfg['ipv6'])) + $ipfrules .= "pass out route-to ( {$ifcfg['if']} {$gwv6} ) inet6 from {$ifcfg['ipv6']} to !{$ifcfg['sav6']}/{$ifcfg['snv6']} keep state allow-opts label \"let out anything from firewall host itself\"\n"; + } + /* add ipsec interfaces */ if(isset($config['ipsec']['enable']) || isset($config['ipsec']['client']['enable'])) @@ -2377,19 +2535,37 @@ EOD; $friendly = $GatewaysList[$route['gateway']]['friendlyiface']; if(is_array($FilterIflist[$friendly])) { $oc = $FilterIflist[$friendly]; - if($oc['ip']) { - $sa = $oc['sa']; - $sn = $oc['sn']; - $if = $oc['if']; - } - if($sa) { - $ipfrules .= <<<EOD + if(is_ipaddrv4($route['network'])) { + if($oc['ip']) { + $sa = $oc['sa']; + $sn = $oc['sn']; + $if = $oc['if']; + } + if($sa) { + $ipfrules .= <<<EOD pass quick on \${$oc['descr']} proto tcp from {$sa}/{$sn} to {$route['network']} flags any keep state(sloppy) label "pass traffic between statically routed subnets" pass quick on \${$oc['descr']} from {$sa}/{$sn} to {$route['network']} keep state(sloppy) label "pass traffic between statically routed subnets" pass quick on \${$oc['descr']} proto tcp from {$route['network']} to {$sa}/{$sn} flags any keep state(sloppy) label "pass traffic between statically routed subnets" pass quick on \${$oc['descr']} from {$route['network']} to {$sa}/{$sn} keep state(sloppy) label "pass traffic between statically routed subnets" EOD; + } + } + if(is_ipaddrv6($route['network'])) { + if($oc['ipv6']) { + $sa = $oc['sav6']; + $sn = $oc['snv6']; + $if = $oc['if']; + } + if($sa) { + $ipfrules .= <<<EOD +pass quick on \${$oc['descr']} inet6 proto tcp from {$sa}/{$sn} to {$route['network']} flags any keep state(sloppy) label "pass traffic between statically routed subnets" +pass quick on \${$oc['descr']} inet6 from {$sa}/{$sn} to {$route['network']} keep state(sloppy) label "pass traffic between statically routed subnets" +pass quick on \${$oc['descr']} inet6 proto tcp from {$route['network']} to {$sa}/{$sn} flags any keep state(sloppy) label "pass traffic between statically routed subnets" +pass quick on \${$oc['descr']} inet6 from {$route['network']} to {$sa}/{$sn} keep state(sloppy) label "pass traffic between statically routed subnets" + +EOD; + } } } } diff --git a/etc/inc/filter_log.inc b/etc/inc/filter_log.inc index ed4b311..1c0e9ef 100644 --- a/etc/inc/filter_log.inc +++ b/etc/inc/filter_log.inc @@ -135,6 +135,8 @@ function parse_filter_line($line) { * boolean FALSE because it could return a valid answer of 0 upon success. */ if (!(strpos($details, 'proto ') === FALSE)) { preg_match("/.*\sproto\s(.*)\s\(/", $details, $proto); + } elseif (!(strpos($details, 'next-header ') === FALSE)) { + preg_match("/.*\snext-header\s(.*)\s\(/", $details, $proto); } elseif (!(strpos($details, 'proto: ') === FALSE)) { preg_match("/.*\sproto\:(.*)\s\(/", $details, $proto); } elseif (!(strpos($leftovers, 'sum ok] ') === FALSE)) { @@ -279,4 +281,4 @@ function handle_ajax($nentries, $tail = 50) { } } -?>
\ No newline at end of file +?> diff --git a/etc/inc/globals.inc b/etc/inc/globals.inc index 6993148..735ea52 100644 --- a/etc/inc/globals.inc +++ b/etc/inc/globals.inc @@ -91,7 +91,7 @@ $g = array( "disablecrashreporter" => false, "crashreporterurl" => "http://crashreporter.pfsense.org/crash_reporter.php", "debug" => false, - "latest_config" => "7.9", + "latest_config" => "8.1", "nopkg_platforms" => array("cdrom"), "minimum_ram_warning" => "101", "minimum_ram_warning_text" => "128 MB", diff --git a/etc/inc/gwlb.inc b/etc/inc/gwlb.inc index 9b4c32b..de9b746 100644 --- a/etc/inc/gwlb.inc +++ b/etc/inc/gwlb.inc @@ -145,7 +145,12 @@ EOD; } /* Interface ip is needed since apinger will bind a socket to it. */ - $gwifip = find_interface_ip($gateway['interface'], true); + if (is_ipaddrv4($gateway['gateway'])) { + $gwifip = find_interface_ip($gateway['interface'], true); + } + if (is_ipaddrv6($gateway['gateway'])) { + $gwifip = find_interface_ipv6($gateway['interface'], true); + } if (!is_ipaddr($gwifip)) continue; //Skip this target @@ -539,35 +544,63 @@ function lookup_gateway_interface_by_name($name) { } function get_interface_gateway($interface, &$dynamic = false) { - global $config, $g; + global $config, $g; - $gw = NULL; + $gw = NULL; - $gwcfg = $config['interfaces'][$interface]; - if (!empty($gwcfg['gateway']) && is_array($config['gateways']['gateway_item'])) { - foreach($config['gateways']['gateway_item'] as $gateway) { - if ($gateway['name'] == $gwcfg['gateway']) { - $gw = $gateway['gateway']; + $gwcfg = $config['interfaces'][$interface]; + if (!empty($gwcfg['gateway']) && is_array($config['gateways']['gateway_item'])) { + foreach($config['gateways']['gateway_item'] as $gateway) { + if(($gateway['name'] == $gwcfg['gateway']) && (is_ipaddrv4($gateway['gateway']))) { + $gw = $gateway['gateway']; break; } - } + } } - // for dynamic interfaces we handle them through the $interface_router file. - if (!is_ipaddr($gw) && !is_ipaddr($gwcfg['ipaddr'])) { - $realif = get_real_interface($interface); - if (file_exists("{$g['tmp_path']}/{$realif}_router")) { - $gw = trim(file_get_contents("{$g['tmp_path']}/{$realif}_router"), " \n"); - $dynamic = true; - } - if (file_exists("{$g['tmp_path']}/{$realif}_defaultgw")) - $dynamic = "default"; + // for dynamic interfaces we handle them through the $interface_router file. + if (!is_ipaddr($gw) && !is_ipaddr($gwcfg['ipaddr'])) { + $realif = get_real_interface($interface); + if (file_exists("{$g['tmp_path']}/{$realif}_router")) { + $gw = trim(file_get_contents("{$g['tmp_path']}/{$realif}_router"), " \n"); + $dynamic = true; + } + if (file_exists("{$g['tmp_path']}/{$realif}_defaultgw")) + $dynamic = "default"; - - } + } - /* return gateway */ - return ($gw); + /* return gateway */ + return ($gw); +} + +function get_interface_gateway_v6($interface, &$dynamic = false) { + global $config, $g; + + $gw = NULL; + $gwcfg = $config['interfaces'][$interface]; + if (!empty($gwcfg['gatewayv6']) && is_array($config['gateways']['gateway_item'])) { + foreach($config['gateways']['gateway_item'] as $gateway) { + if(($gateway['name'] == $gwcfg['gatewayv6']) && (is_ipaddrv6($gateway['gateway']))) { + $gw = $gateway['gateway']; + break; + } + } + } + + // for dynamic interfaces we handle them through the $interface_router file. + if (!is_ipaddrv6($gw) && !is_ipaddr($gwcfg['ipaddrv6'])) { + $realif = get_real_interface($interface); + if (file_exists("{$g['tmp_path']}/{$realif}_routerv6")) { + $gw = trim(file_get_contents("{$g['tmp_path']}/{$realif}_routerv6"), " \n"); + $dynamic = true; + } + if (file_exists("{$g['tmp_path']}/{$realif}_defaultgwv6")) + $dynamic = "default"; + + } + /* return gateway */ + return ($gw); } ?> diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index 63f380a..480d1b6 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -37,6 +37,7 @@ pfSense_BUILDER_BINARIES: /sbin/dhclient /bin/sh /usr/bin/grep /usr/bin/xargs /usr/bin/awk /usr/local/sbin/choparp pfSense_BUILDER_BINARIES: /sbin/ifconfig /sbin/route /usr/sbin/ngctl /usr/sbin/arp /bin/kill /usr/local/sbin/mpd5 + pfSense_BUILDER_BINARIES: /usr/local/sbin/dhcp6c pfSense_MODULE: interfaces */ @@ -746,7 +747,10 @@ function interface_gre_configure(&$gre, $grekey = "") { if (isset($gre['link1']) && $gre['link1']) mwexec("/sbin/route add {$gre['tunnel-remote-addr']}/{$gre['tunnel-remote-net']} {$gre['tunnel-local-addr']}"); - file_put_contents("{$g['tmp_path']}/{$greif}_router", $gre['tunnel-remote-addr']); + if(is_ipaddrv4($gre['tunnel-remote-addr'])) + file_put_contents("{$g['tmp_path']}/{$greif}_router", $gre['tunnel-remote-addr']); + if(is_ipaddrv6($gre['tunnel-remote-addr'])) + file_put_contents("{$g['tmp_path']}/{$greif}_routerv6", $gre['tunnel-remote-addr']); return $greif; } @@ -793,7 +797,11 @@ function interface_gif_configure(&$gif, $gifkey = "") { /* Do not change the order here for more see gif(4) NOTES section. */ mwexec("/sbin/ifconfig {$gifif} tunnel {$realifip} {$gif['remote-addr']}"); - mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net'])); + if((is_ipaddrv6($gif['tunnel-local-addr'])) || (is_ipaddrv6($gif['tunnel-remote-addr']))) { + mwexec("/sbin/ifconfig {$gifif} inet6 {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} prefixlen {$gif['tunnel-remote-net']} "); + } else { + mwexec("/sbin/ifconfig {$gifif} {$gif['tunnel-local-addr']} {$gif['tunnel-remote-addr']} netmask " . gen_subnet_mask($gif['tunnel-remote-net'])); + } if (isset($gif['link0']) && $gif['link0']) pfSense_interface_flags($gifif, IFF_LINK0); if (isset($gif['link1']) && $gif['link1']) @@ -803,9 +811,24 @@ function interface_gif_configure(&$gif, $gifkey = "") { else log_error("could not bring gifif up -- variable not defined"); - /* XXX: Needed?! */ - //mwexec("/sbin/route add {$gif['tunnel-remote-addr']}/{$gif['tunnel-remote-net']} -iface {$gifif}"); - file_put_contents("{$g['tmp_path']}/{$gifif}_router", $gif['tunnel-remote-addr']); + $iflist = get_configured_interface_list(); + foreach($iflist as $ifname) { + if($config['interfaces'][$ifname]['if'] == $gifif) { + if(get_interface_gateway($ifname)) { + system_routing_configure($ifname); + break; + } + if(get_interface_gateway_v6($ifname)) { + system_routing_configure($ifname); + break; + } + } + } + + if(is_ipaddrv4($gif['tunnel-remote-addr'])) + file_put_contents("{$g['tmp_path']}/{$gifif}_router", $gif['tunnel-remote-addr']); + if(is_ipaddrv6($gif['tunnel-remote-addr'])) + file_put_contents("{$g['tmp_path']}/{$gifif}_routerv6", $gif['tunnel-remote-addr']); return $gifif; } @@ -1005,8 +1028,12 @@ function interface_bring_down($interface = "wan", $destroy = false) { $pid = find_dhclient_process($realif); if($pid) mwexec("/bin/kill {$pid}"); + $pidv6 = find_dhcp6c_process($realif); + if($pidv6) + mwexec("/bin/kill {$pidv6}"); sleep(1); unlink_if_exists("{$g['varetc_path']}/dhclient_{$interface}.conf"); + unlink_if_exists("{$g['varetc_path']}/dhcp6c_{$interface}.conf"); if(does_interface_exist("$realif")) { mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true); if ($destroy == true) @@ -1027,7 +1054,9 @@ function interface_bring_down($interface = "wan", $destroy = false) { /* remove interface up file if it exists */ unlink_if_exists("{$g['tmp_path']}/{$realif}up"); unlink_if_exists("{$g['vardb_path']}/{$interface}ip"); + unlink_if_exists("{$g['vardb_path']}/{$interface}ipv6"); unlink_if_exists("{$g['tmp_path']}/{$realif}_router"); + unlink_if_exists("{$g['tmp_path']}/{$realif}_routerv6"); unlink_if_exists("{$g['varetc_path']}/nameserver_{$realif}"); unlink_if_exists("{$g['varetc_path']}/searchdomain_{$realif}"); @@ -1333,6 +1362,7 @@ startup: default: {$ppp['type']}client: create bundle static {$interface} + set bundle enable ipv6cp set iface name {$pppif} EOD; @@ -1842,12 +1872,23 @@ function interface_carp_configure(&$vip) { return; } - /* Ensure CARP IP really exists prior to loading up. */ - $ww_subnet_ip = find_interface_ip($realif); - $ww_subnet_bits = find_interface_subnet($realif); - if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) { - file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", ""); - return; + if(is_ipaddrv4($vip['subnet'])) { + /* Ensure CARP IP really exists prior to loading up. */ + $ww_subnet_ip = find_interface_ip($realif); + $ww_subnet_bits = find_interface_subnet($realif); + if (!ip_in_subnet($vip['subnet'], gen_subnet($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) { + file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IP address {$vip['subnet']}.", "Firewall: Virtual IP", ""); + return; + } + } + if(is_ipaddrv6($vip['subnet'])) { + /* Ensure CARP IP really exists prior to loading up. */ + $ww_subnet_ip = find_interface_ipv6($realif); + $ww_subnet_bits = find_interface_subnetv6($realif); + if (!ip_in_subnet($vip['subnet'], gen_subnetv6($ww_subnet_ip, $ww_subnet_bits) . "/" . $ww_subnet_bits) && !ip_in_interface_alias_subnet($vip['interface'], $vip['subnet'])) { + file_notice("CARP", "Sorry but we could not find a matching real interface subnet for the virtual IPv6 address {$vip['subnet']}.", "Firewall: Virtual IP", ""); + return; + } } /* create the carp interface and setup */ @@ -1862,11 +1903,18 @@ function interface_carp_configure(&$vip) { /* invalidate interface cache */ get_interface_arr(true); - $broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']); $advbase = ""; if (!empty($vip['advbase'])) $advbase = "advbase {$vip['advbase']}"; - mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}"); + + if(is_ipaddrv4($vip['subnet'])) { + $broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']); + mwexec("/sbin/ifconfig {$vipif} {$vip['subnet']}/{$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}"); + } + if(is_ipaddrv6($vip['subnet'])) { + $broadcast_address = gen_subnet_max($vip['subnet'], $vip['subnet_bits']); + mwexec("/sbin/ifconfig {$vipif} inet6 {$vip['subnet']} prefixlen {$vip['subnet_bits']} vhid {$vip['vhid']} advskew {$vip['advskew']} {$advbase} {$password}"); + } interfaces_bring_up($vipif); @@ -2507,9 +2555,19 @@ function find_dhclient_process($interface) { return intval($pid); } +function find_dhcp6c_process($interface) { + if ($interface) + $pid = `/bin/ps auxw|grep "dhcp6c" |grep "{$interface}"|awk '{print $2}'`; + else + $pid = 0; + + return intval($pid); +} + function interface_configure($interface = "wan", $reloadall = false, $linkupevent = false) { global $config, $g; global $interface_sn_arr_cache, $interface_ip_arr_cache; + global $interface_snv6_arr_cache, $interface_ipv6_arr_cache; $wancfg = $config['interfaces'][$interface]; @@ -2520,8 +2578,11 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven if (!$g['booting'] && !substr($realif, 0, 4) == "ovpn") { - /* remove all IPv4 addresses */ + /* remove all IPv4 and IPv6 addresses */ while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0); + while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -alias", true) == 0); + /* Disable Accepting router advertisements unless specifically requested */ + while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -accept_rtadv") == 0); switch ($wancfg['ipaddr']) { case 'pppoe': @@ -2641,6 +2702,8 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven get_interface_arr(true); unset($interface_ip_arr_cache[$realif]); unset($interface_sn_arr_cache[$realif]); + unset($interface_ipv6_arr_cache[$realif]); + unset($interface_snv6_arr_cache[$realif]); switch ($wancfg['ipaddr']) { case 'carpdev-dhcp': @@ -2676,6 +2739,16 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven break; } + switch ($wancfg['ipaddrv6']) { + default: + if ($wancfg['ipaddrv6'] <> "" && $wancfg['subnetv6'] <> "") { + pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}"); + // FIXME: Add IPv6 Support to the pfSense module + mwexec("/sbin/ifconfig {$realif} inet6 {$wancfg['ipaddrv6']} prefixlen {$wancfg['subnetv6']} "); + } + break; + } + if(does_interface_exist($wancfg['if'])) interfaces_bring_up($wancfg['if']); @@ -2749,6 +2822,88 @@ function interface_dhcp_configure($interface = "wan") { global $config, $g; $wancfg = $config['interfaces'][$interface]; + $wanif = $wancfg['if']; + if (empty($wancfg)) + $wancfg = array(); + + $wanif = get_real_interface($interface); + /* bring wan interface up before starting dhclient */ + if($wanif) + interfaces_bring_up($wanif); + else + log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()"); + + /* launch v6 before v4, dhclient can hold up the execution if no dhcp4 is available */ + interface_dhcpv6_configure($interface); + interface_dhcpv4_configure($interface); + + return 0; + +} + +function interface_dhcpv6_configure($interface = "wan") { + global $config, $g; + $iflist = get_configured_interface_with_descr(false, true); + + $wancfg = $config['interfaces'][$interface]; + $wanif = $wancfg['if']; + if (empty($wancfg)) + $wancfg = array(); + + $wanif = get_real_interface($interface); + + /* Add IPv6 dhclient here, only wide-dhcp6c works for now. */ + $fd = fopen("{$g['varetc_path']}/dhcp6c_{$interface}.conf", "w"); + if (!$fd) { + printf("Error: cannot open dhcp6c_{$interface}.conf in interfaces_wan_dhcp_configure() for writing.\n"); + return 1; + } + + $dhcp6cconf = ""; + $dhcp6cconf .= "interface {$wanif} {\n"; + $dhcp6cconf .= " send ia-na 0; # request stateful address\n"; + if(is_numeric($wancfg['dhcp6-ia-pd-len'])) { + $dhcp6cconf .= " send ia-pd 0; # request prefix delegation\n"; + } + $dhcp6cconf .= "request domain-name-servers;\n"; + $dhcp6cconf .= "request domain-name;\n"; + $dhcp6cconf .= "script \"/etc/rc.newwanipv6\"; # we'd like some nameservers please\n"; + + $dhcp6cconf .= "};\n"; + $dhcp6cconf .= "id-assoc na 0 { };\n"; + if(is_numeric($wancfg['dhcp6-ia-pd-len'])) { + /* Setup the prefix delegation */ + $dhcp6cconf .= " id-assoc pd 0 {\n"; + foreach($iflist as $friendly => $pdinterface) { + // log_error("setting up $friendly - $pdinterface - {$pdinterface['dhcp6-pd-sla-id']}"); + if(is_numeric($config['interfaces'][$friendly]['dhcp6-pd-sla-id'])) { + $realif = get_real_interface($friendly); + $dhcp6cconf .= " prefix-interface {$realif} {\n"; + $dhcp6cconf .= " sla-id {$config['interfaces'][$friendly]['dhcp6-pd-sla-id']};\n"; + $dhcp6cconf .= " sla-len {$wancfg['dhcp6-ia-pd-len']};\n"; + $dhcp6cconf .= " };\n"; + } + } + $dhcp6cconf .= "};\n"; + } + + fwrite($fd, $dhcp6cconf); + fclose($fd); + + /* accept router advertisements for this interface */ + // mwexec("/sbin/sysctl -w net.inet6.ip6.accept_rtadv=1"); + mwexec("/sbin/ifconfig {$wanif} inet6 accept_rtadv"); + /* fire up dhcp6c for IPv6 first, this backgrounds immediately */ + mwexec("/usr/local/sbin/dhcp6c -d -c {$g['varetc_path']}/dhcp6c_{$interface}.conf {$wanif}"); + + return 0; +} + +function interface_dhcpv4_configure($interface = "wan") { + global $config, $g; + + $wancfg = $config['interfaces'][$interface]; + $wanif = $wancfg['if']; if (empty($wancfg)) $wancfg = array(); @@ -2799,12 +2954,6 @@ EOD; fwrite($fd, $dhclientconf); fclose($fd); - /* bring wan interface up before starting dhclient */ - if($wanif) - interfaces_bring_up($wanif); - else - log_error("Could not bring up {$wanif} interface in interface_dhcp_configure()"); - /* fire up dhclient */ mwexec("/sbin/dhclient -c {$g['varetc_path']}/dhclient_{$interface}.conf {$wanif} > {$g['tmp_path']}/{$wanif}_output > {$g['tmp_path']}/{$wanif}_error_output"); @@ -3131,13 +3280,28 @@ function guess_interface_from_ip($ipaddress) { if(! is_ipaddr($ipaddress)) { return false; } - /* create a route table we can search */ - exec("netstat -rnWf inet", $output, $ret); - foreach($output as $line) { - if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) { - $fields = preg_split("/[ ]+/", $line); - if(ip_in_subnet($ipaddress, $fields[0])) { - return $fields[6]; + if(is_ipaddrv4($ipaddress)) { + /* create a route table we can search */ + exec("netstat -rnWf inet", $output, $ret); + foreach($output as $line) { + if(preg_match("/^[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+\/[0-9]+[ ]+link[#]/", $line)) { + $fields = preg_split("/[ ]+/", $line); + if(ip_in_subnet($ipaddress, $fields[0])) { + return $fields[6]; + } + } + } + } + /* FIXME: This works from cursory testing, regexp might need fine tuning */ + if(is_ipaddrv6($ipaddress)) { + /* create a route table we can search */ + exec("netstat -rnWf inet6", $output, $ret); + foreach($output as $line) { + if(preg_match("/[0-9a-f]+[:]+[0-9a-f]+[:]+[\/][0-9]+/", $line)) { + $fields = preg_split("/[ ]+/", $line); + if(ip_in_subnet($ipaddress, $fields[0])) { + return $fields[6]; + } } } } @@ -3186,8 +3350,22 @@ function find_carp_interface($ip) { if (is_array($config['virtualip']['vip'])) { foreach ($config['virtualip']['vip'] as $vip) { if ($vip['mode'] == "carp" || $vip['mode'] == "carpdev") { - $carp_ip = get_interface_ip($vip['interface']); - $if = `ifconfig | grep '$ip ' -B1 | head -n1 | cut -d: -f1`; + if(is_ipaddrv4($ip)) { + $carp_ip = get_interface_ip($vip['interface']); + } + if(is_ipaddrv6($ip)) { + $carp_ip = get_interface_ipv6($vip['interface']); + } + exec("/sbin/ifconfig", $output, $return); + foreach($output as $line) { + $elements = preg_split("/[ ]+/i", $line); + if(strstr($elements[0], "vip")) + $curif = str_replace(":", "", $elements[0]); + if(stristr($line, $ip)) { + $if = $curif; + continue; + } + } if ($if) return $if; } @@ -3371,6 +3549,46 @@ function find_interface_ip($interface, $flush = false) return $interface_ip_arr_cache[$interface]; } +/* + * find_interface_ipv6($interface): return the interface ip (first found) + */ +function find_interface_ipv6($interface, $flush = false) +{ + global $interface_ipv6_arr_cache; + global $interface_snv6_arr_cache; + global $config; + + $interface = str_replace("\n", "", $interface); + + if (!does_interface_exist($interface)) + return; + + /* Setup IP cache */ + if (!isset($interface_ipv6_arr_cache[$interface]) or $flush) { + $ifinfo = pfSense_get_interface_addresses($interface); + // FIXME: Add IPv6 support to the pfSense module + exec("/sbin/ifconfig {$interface} inet6", $output); + foreach($output as $line) { + if(preg_match("/inet6/", $line)) { + $parts = explode(" ", $line); + if(! preg_match("/fe80::/", $parts[1])) { + $ifinfo['ipaddrv6'] = $parts[1]; + if($parts[2] == "-->") { + $parts[5] = "126"; + $ifinfo['subnetbitsv6'] = $parts[5]; + } else { + $ifinfo['subnetbitsv6'] = $parts[3]; + } + } + } + } + $interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6']; + $interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6']; + } + + return $interface_ipv6_arr_cache[$interface]; +} + function find_interface_subnet($interface, $flush = false) { global $interface_sn_arr_cache; @@ -3389,6 +3607,40 @@ function find_interface_subnet($interface, $flush = false) return $interface_sn_arr_cache[$interface]; } +function find_interface_subnetv6($interface, $flush = false) +{ + global $interface_snv6_arr_cache; + global $interface_ipv6_arr_cache; + + $interface = str_replace("\n", "", $interface); + if (does_interface_exist($interface) == false) + return; + + if (!isset($interface_snv6_arr_cache[$interface]) or $flush) { + $ifinfo = pfSense_get_interface_addresses($interface); + // FIXME: Add IPv6 support to the pfSense module + exec("/sbin/ifconfig {$interface} inet6", $output); + foreach($output as $line) { + if(preg_match("/inet6/", $line)) { + $parts = explode(" ", $line); + if(! preg_match("/fe80::/", $parts[1])) { + $ifinfo['ipaddrv6'] = $parts[1]; + if($parts[2] == "-->") { + $parts[5] = "126"; + $ifinfo['subnetbitsv6'] = $parts[5]; + } else { + $ifinfo['subnetbitsv6'] = $parts[3]; + } + } + } + } + $interface_ipv6_arr_cache[$interface] = $ifinfo['ipaddrv6']; + $interface_snv6_arr_cache[$interface] = $ifinfo['subnetbitsv6']; + } + + return $interface_snv6_arr_cache[$interface]; +} + function ip_in_interface_alias_subnet($interface, $ipalias) { global $config; @@ -3429,6 +3681,25 @@ function get_interface_ip($interface = "wan") return null; } +function get_interface_ipv6($interface = "wan") +{ + $realif = get_real_interface($interface); + if (!$realif) { + if (preg_match("/^carp/i", $interface)) + $realif = $interface; + else if (preg_match("/^vip/i", $interface)) + $realif = $interface; + else + return null; + } + + $curip = find_interface_ipv6($realif); + if ($curip && is_ipaddrv6($curip) && ($curip != "::")) + return $curip; + else + return null; +} + function get_interface_subnet($interface = "wan") { $realif = get_real_interface($interface); @@ -3448,6 +3719,25 @@ function get_interface_subnet($interface = "wan") return null; } +function get_interface_subnetv6($interface = "wan") +{ + $realif = get_real_interface($interface); + if (!$realif) { + if (preg_match("/^carp/i", $interface)) + $realif = $interface; + else if (preg_match("/^vip/i", $interface)) + $realif = $interface; + else + return null; + } + + $cursn = find_interface_subnetv6($realif); + if (!empty($cursn)) + return $cursn; + + return null; +} + /* return outside interfaces with a gateway */ function get_interfaces_with_gateway() { global $config; diff --git a/etc/inc/ipsec.inc b/etc/inc/ipsec.inc index e15a14c..fad5d6a 100644 --- a/etc/inc/ipsec.inc +++ b/etc/inc/ipsec.inc @@ -82,7 +82,8 @@ $p1_authentication_methods = array( 'pre_shared_key' => array( 'name' => 'Mutual PSK', 'mobile' => false ) ); $p2_modes = array( - 'tunnel' => 'Tunnel', + 'tunnel' => 'Tunnel IPv4', + 'tunnel6' => 'Tunnel IPv6', 'transport' => 'Transport'); $p2_protos = array( @@ -126,14 +127,21 @@ function ipsec_get_phase1_src(& $ph1ent) { if ($ph1ent['interface']) { if (!is_ipaddr($ph1ent['interface'])) { $if = $ph1ent['interface']; - $interfaceip = get_interface_ip($if); + if($ph1ent['protocol'] == "inet6") { + $interfaceip = get_interface_ipv6($if); + } else { + $interfaceip = get_interface_ip($if); + } } else { $interfaceip=$ph1ent['interface']; } - } - else { + } else { $if = "wan"; - $interfaceip = get_interface_ip($if); + if($ph1ent['protocol'] == "inet6") { + $interfaceip = get_interface_ipv6($if); + } else { + $interfaceip = get_interface_ip($if); + } } return $interfaceip; @@ -165,21 +173,33 @@ function ipsec_idinfo_to_cidr(& $idinfo,$addrbits = false) { switch ($idinfo['type']) { case "address": - if ($addrbits) - return $idinfo['address']."/32"; - else + if ($addrbits) { + if($idinfo['mode'] == "tunnel6") { + return $idinfo['address']."/128"; + } else { + return $idinfo['address']."/32"; + } + } else { return $idinfo['address']; + } case "network": return $idinfo['address']."/".$idinfo['netbits']; case "none": case "mobile": return "0.0.0.0/0"; default: - $address = get_interface_ip($idinfo['type']); - $netbits = get_interface_subnet($idinfo['type']); - $address = gen_subnet($address,$netbits); - return $address."/".$netbits; - } + if($idinfo['mode'] == "tunnel6") { + $address = get_interface_ipv6($idinfo['type']); + $netbits = get_interface_subnetv6($idinfo['type']); + $address = gen_subnetv6($address,$netbits); + return $address."/".$netbits; + } else { + $address = get_interface_ip($idinfo['type']); + $netbits = get_interface_subnet($idinfo['type']); + $address = gen_subnet($address,$netbits); + return $address."/".$netbits; + } + } } /* @@ -191,22 +211,33 @@ function ipsec_idinfo_to_subnet(& $idinfo,$addrbits = false) { switch ($idinfo['type']) { case "address": - if ($addrbits) - return $idinfo['address']."/255.255.255.255"; - else + if ($addrbits) { + if($idinfo['mode'] == "tunnel6") { + return $idinfo['address']."/128"; + } else { + return $idinfo['address']."/255.255.255.255"; + } + } else { return $idinfo['address']; + } case "none": case "network": return $idinfo['address']."/".gen_subnet_mask($idinfo['netbits']); case "mobile": return "0.0.0.0/0"; default: - $address = get_interface_ip($idinfo['type']); - $netbits = get_interface_subnet($idinfo['type']); - $address = gen_subnet($address,$netbits); - $netbits = gen_subnet_mask($netbits); - return $address."/".netbits; - } + if($idinfo['mode'] == "tunnel6") { + $address = get_interface_ipv6($idinfo['type']); + $netbits = get_interface_subnetv6($idinfo['type']); + $address = gen_subnetv6($address,$netbits); + return $address."/".$netbits; + } else { + $address = get_interface_ip($idinfo['type']); + $netbits = get_interface_subnet($idinfo['type']); + $address = gen_subnet($address,$netbits); + return $address."/".$netbits; + } + } } /* @@ -269,7 +300,7 @@ function ipsec_phase1_status(& $ph1ent) { function ipsec_phase2_status(& $spd,& $sad,& $ph1ent,& $ph2ent) { $loc_ip = ipsec_get_phase1_src($ph1ent); - $rmt_ip = gethostbyname(ipsec_get_phase1_dst($ph1ent)); + $rmt_ip = resolve_retry(ipsec_get_phase1_dst($ph1ent)); $loc_id = ipsec_idinfo_to_cidr($ph2ent['localid'],true); $rmt_id = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true); diff --git a/etc/inc/openvpn.inc b/etc/inc/openvpn.inc index 7f82975..87d64ce 100644 --- a/etc/inc/openvpn.inc +++ b/etc/inc/openvpn.inc @@ -328,20 +328,31 @@ function openvpn_reconfigure($mode, $settings) { $interface = $settings['interface']; $ipaddr = $settings['ipaddr']; + $ipaddrv6 = $settings['ipaddrv6']; // If a specific ip address (VIP) is requested, use it. // Otherwise, if a specific interface is requested, use it // If "any" interface was selected, local directive will be ommited. - if (!empty($ipaddr)) { + if (is_ipaddrv4($ipaddr)) { $iface_ip=$ipaddr; + } elseif (is_ipaddrv6($ipaddrv6)) { + $iface_ipv6=$ipaddrv6; } else { if ((!empty($interface)) && (strcmp($interface, "any"))) { $iface_ip=get_interface_ip($interface); } + if ((!empty($interface)) && (strcmp($interface, "any"))) { + $iface_ipv6=get_interface_ipv6($interface); + } } $conf = "dev {$devname}\n"; $conf .= "dev-type {$settings['dev_mode']}\n"; + switch($settings['dev_mode']) { + case "tun": + $conf .= "tun-ipv6\n"; + break; + } $conf .= "dev-node /dev/{$tunname}\n"; $conf .= "writepid {$pfile}\n"; $conf .= "#user nobody\n"; @@ -357,9 +368,12 @@ function openvpn_reconfigure($mode, $settings) { $conf .= "up /usr/local/sbin/ovpn-linkup\n"; $conf .= "down /usr/local/sbin/ovpn-linkdown\n"; - if (!empty($iface_ip)) { + if (is_ipaddrv4($iface_ip)) { $conf .= "local {$iface_ip}\n"; } + if (is_ipaddrv6($iface_ipv6)) { + // $conf .= "local {$iface_ipv6}\n"; + } if (openvpn_validate_engine($settings['engine']) && ($settings['engine'] != "none")) $conf .= "engine {$settings['engine']}\n"; @@ -368,6 +382,7 @@ function openvpn_reconfigure($mode, $settings) { if ($mode == 'server') { list($ip, $mask) = explode('/', $settings['tunnel_network']); + list($ipv6, $prefix) = explode('/', $settings['tunnel_networkv6']); $mask = gen_subnet_mask($mask); // configure tls modes @@ -395,6 +410,8 @@ function openvpn_reconfigure($mode, $settings) { case 'server_user': case 'server_tls_user': $conf .= "server {$ip} {$mask}\n"; + if(is_ipaddr($ipv6)) + $conf .= "server-ipv6 {$ipv6}/{$prefix}\n"; $conf .= "client-config-dir {$g['varetc_path']}/openvpn-csc\n"; break; } @@ -443,6 +460,10 @@ function openvpn_reconfigure($mode, $settings) { $mask = gen_subnet_mask($mask); $conf .= "push \"route $ip $mask\"\n"; } + if ($settings['local_networkv6']) { + list($ipv6, $prefix) = explode('/', $settings['local_networkv6']); + $conf .= "push \"route-ipv6 $ipv6/$prefix\"\n"; + } switch($settings['mode']) { case 'server_tls': diff --git a/etc/inc/pfsense-utils.inc b/etc/inc/pfsense-utils.inc index c75ae20..ddbecbb 100644 --- a/etc/inc/pfsense-utils.inc +++ b/etc/inc/pfsense-utils.inc @@ -1037,15 +1037,26 @@ function is_dhcp_server_enabled() $dhcpdenable = false; - if (!is_array($config['dhcpd'])) + if ((!is_array($config['dhcpd'])) && (!is_array($config['dhcpdv6']))) return false; $Iflist = get_configured_interface_list(); - foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) { - if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) { - $dhcpdenable = true; - break; + if(is_array($config['dhcpd'])) { + foreach ($config['dhcpd'] as $dhcpif => $dhcpifconf) { + if (isset($dhcpifconf['enable']) && isset($Iflist[$dhcpif])) { + $dhcpdenable = true; + break; + } + } + } + + if(is_array($config['dhcpdv6'])) { + foreach ($config['dhcpdv6'] as $dhcpv6if => $dhcpv6ifconf) { + if (isset($dhcpv6ifconf['enable']) && isset($Iflist[$dhcpv6if])) { + $dhcpdenable = true; + break; + } } } @@ -1123,11 +1134,13 @@ function get_interface_info($ifdescr) { $ifinfo['macaddr'] = $ifinfotmp['macaddr']; $ifinfo['ipaddr'] = $ifinfotmp['ipaddr']; $ifinfo['subnet'] = $ifinfotmp['subnet']; + $ifinfo['ipaddrv6'] = get_interface_ipv6($ifdescr); + $ifinfo['subnetv6'] = get_interface_subnetv6($ifdescr); if (isset($ifinfotmp['link0'])) $link0 = "down"; $ifinfotmp = pfSense_get_interface_stats($chkif); - $ifinfo['inpkts'] = $ifinfotmp['inpkts']; - $ifinfo['outpkts'] = $ifinfotmp['outpkts']; + // $ifinfo['inpkts'] = $ifinfotmp['inpkts']; + // $ifinfo['outpkts'] = $ifinfotmp['outpkts']; $ifinfo['inerrs'] = $ifinfotmp['inerrs']; $ifinfo['outerrs'] = $ifinfotmp['outerrs']; $ifinfo['collisions'] = $ifinfotmp['collisions']; @@ -1137,31 +1150,43 @@ function get_interface_info($ifdescr) { exec("/sbin/pfctl -vvsI -i {$chkif}", $pfctlstats); $pf_in4_pass = preg_split("/ +/ ", $pfctlstats[3]); $pf_out4_pass = preg_split("/ +/", $pfctlstats[5]); + $pf_in6_pass = preg_split("/ +/ ", $pfctlstats[7]); + $pf_out6_pass = preg_split("/ +/", $pfctlstats[9]); $in4_pass = $pf_in4_pass[5]; $out4_pass = $pf_out4_pass[5]; $in4_pass_packets = $pf_in4_pass[3]; $out4_pass_packets = $pf_out4_pass[3]; - $ifinfo['inbytespass'] = $in4_pass; - $ifinfo['outbytespass'] = $out4_pass; - $ifinfo['inpktspass'] = $in4_pass_packets; - $ifinfo['outpktspass'] = $out4_pass_packets; + $in6_pass = $pf_in6_pass[5]; + $out6_pass = $pf_out6_pass[5]; + $in6_pass_packets = $pf_in6_pass[3]; + $out6_pass_packets = $pf_out6_pass[3]; + $ifinfo['inbytespass'] = $in4_pass + $in6_pass; + $ifinfo['outbytespass'] = $out4_pass + $out6_pass; + $ifinfo['inpktspass'] = $in4_pass_packets + $in6_pass_packets; + $ifinfo['outpktspass'] = $out4_pass_packets + $in6_pass_packets; /* Block */ $pf_in4_block = preg_split("/ +/", $pfctlstats[4]); $pf_out4_block = preg_split("/ +/", $pfctlstats[6]); + $pf_in6_block = preg_split("/ +/", $pfctlstats[8]); + $pf_out6_block = preg_split("/ +/", $pfctlstats[10]); $in4_block = $pf_in4_block[5]; $out4_block = $pf_out4_block[5]; $in4_block_packets = $pf_in4_block[3]; $out4_block_packets = $pf_out4_block[3]; - $ifinfo['inbytesblock'] = $in4_block; - $ifinfo['outbytesblock'] = $out4_block; - $ifinfo['inpktsblock'] = $in4_block_packets; - $ifinfo['outpktsblock'] = $out4_block_packets; - - $ifinfo['inbytes'] = $in4_pass + $in4_block; - $ifinfo['outbytes'] = $out4_pass + $out4_block; - $ifinfo['inpkts'] = $in4_pass_packets + $in4_block_packets; - $ifinfo['outpkts'] = $in4_pass_packets + $out4_block_packets; + $in6_block = $pf_in6_block[5]; + $out6_block = $pf_out6_block[5]; + $in6_block_packets = $pf_in6_block[3]; + $out6_block_packets = $pf_out6_block[3]; + $ifinfo['inbytesblock'] = $in4_block + $in6_block; + $ifinfo['outbytesblock'] = $out4_block + $out6_block; + $ifinfo['inpktsblock'] = $in4_block_packets + $in6_block_packets; + $ifinfo['outpktsblock'] = $out4_block_packets + $out6_block_packets; + + $ifinfo['inbytes'] = $in4_pass + $in6_pass; + $ifinfo['outbytes'] = $out4_pass + $out6_pass; + $ifinfo['inpkts'] = $in4_pass_packets + $in6_pass_packets; + $ifinfo['outpkts'] = $in4_pass_packets + $out6_pass_packets; $ifconfiginfo = ""; $link_type = $config['interfaces'][$ifdescr]['ipaddr']; @@ -1275,8 +1300,10 @@ function get_interface_info($ifdescr) { } /* lookup the gateway */ - if (interface_has_gateway($ifdescr)) + if (interface_has_gateway($ifdescr)) { $ifinfo['gateway'] = get_interface_gateway($ifdescr); + $ifinfo['gatewayv6'] = get_interface_gateway_v6($ifdescr); + } } $bridge = ""; @@ -2181,6 +2208,37 @@ function filter_rules_compare($a, $b) { return compare_interface_friendly_names($a['interface'], $b['interface']); } +function generate_ipv6_from_mac($mac) { + $elements = explode(":", $mac); + if(count($elements) <> 6) + return false; + + $i = 0; + $ipv6 = "fe80::"; + foreach($elements as $byte) { + if($i == 0) { + $hexadecimal = substr($byte, 1, 2); + $bitmap = base_convert($hexadecimal, 16, 2); + $bitmap = str_pad($bitmap, 4, "0", STR_PAD_LEFT); + $bitmap = substr($bitmap, 0, 2) ."1". substr($bitmap, 3,4); + $byte = substr($byte, 0, 1) . base_convert($bitmap, 2, 16); + } + $ipv6 .= $byte; + if($i == 1) { + $ipv6 .= ":"; + } + if($i == 3) { + $ipv6 .= ":"; + } + if($i == 2) { + $ipv6 .= "ff:fe"; + } + + $i++; + } + return $ipv6; +} + /****f* pfsense-utils/load_mac_manufacturer_table * NAME * load_mac_manufacturer_table @@ -2206,6 +2264,9 @@ function load_mac_manufacturer_table() { return -1; } +<<<<<<< HEAD +?> +======= /****f* pfsense-utils/is_ipaddr_configured * NAME @@ -2245,4 +2306,5 @@ function pfSense_handle_custom_code($src_dir) { } } -?>
\ No newline at end of file +?> +>>>>>>> upstream/master diff --git a/etc/inc/rrd.inc b/etc/inc/rrd.inc index 8ae459b..0475169 100644 --- a/etc/inc/rrd.inc +++ b/etc/inc/rrd.inc @@ -253,6 +253,7 @@ function enable_rrd_graphing() { /* db update script */ $rrdupdatesh = "#!/bin/sh\n"; $rrdupdatesh .= "\n"; + $rrdupdatesh .= "export TERM=dumb\n"; $rrdupdatesh .= "counter=1\n"; $rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n"; $rrdupdatesh .= "do\n"; @@ -284,6 +285,10 @@ function enable_rrd_graphing() { $rrdcreate .= "DS:outpass:COUNTER:$trafficvalid:0:$upstream "; $rrdcreate .= "DS:inblock:COUNTER:$trafficvalid:0:$downstream "; $rrdcreate .= "DS:outblock:COUNTER:$trafficvalid:0:$upstream "; + $rrdcreate .= "DS:inpass6:COUNTER:$trafficvalid:0:$downstream "; + $rrdcreate .= "DS:outpass6:COUNTER:$trafficvalid:0:$upstream "; + $rrdcreate .= "DS:inblock6:COUNTER:$trafficvalid:0:$downstream "; + $rrdcreate .= "DS:outblock6:COUNTER:$trafficvalid:0:$upstream "; $rrdcreate .= "RRA:AVERAGE:0.5:1:1000 "; $rrdcreate .= "RRA:AVERAGE:0.5:5:1000 "; $rrdcreate .= "RRA:AVERAGE:0.5:60:1000 "; @@ -294,17 +299,16 @@ function enable_rrd_graphing() { /* enter UNKNOWN values in the RRD so it knows we rebooted. */ if($g['booting']) { - mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U"); + mwexec("$rrdtool update $rrddbpath$ifname$traffic N:U:U:U:U:U:U:U:U"); } $rrdupdatesh .= "\n"; - $rrdupdatesh .= "# polling traffic for interface $ifname $realif \n"; - $rrdupdatesh .= "TMPFILE=`mktemp -q /tmp/STATS_{$realif}.XXXXXX` \n"; - $rrdupdatesh .= "$pfctl -vvsI -i {$realif} > \$TMPFILE \n"; - $rrdupdatesh .= "unset BYTES \n"; - $rrdupdatesh .= "BYTES=`cat \$TMPFILE | awk '/In4\/Pass|Out4\/Pass/ {printf \$6 \":\"}'`\\\n"; - $rrdupdatesh .= "`cat \$TMPFILE | awk '/In4\/Block|Out4\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n"; - $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:\$BYTES\n"; + $rrdupdatesh .= "# polling traffic for interface $ifname $realif IPv4/IPv6 counters \n"; + $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$traffic N:"; + $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n"; + $rrdupdatesh .= "/In4\/Pass/ { b4pi = \$6 };/Out4\/Pass/ { b4po = \$6 };/In4\/Block/ { b4bi = \$6 };/Out4\/Block/ { b4bo = \$6 };\\\n"; + $rrdupdatesh .= "/In6\/Pass/ { b6pi = \$6 };/Out6\/Pass/ { b6po = \$6 };/In6\/Block/ { b6bi = \$6 };/Out6\/Block/ { b6bo = \$6 };\\\n"; + $rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n"; /* PACKETS, set up the rrd file */ if (!file_exists("$rrddbpath$ifname$packets")) { @@ -313,6 +317,10 @@ function enable_rrd_graphing() { $rrdcreate .= "DS:outpass:COUNTER:$packetsvalid:0:$upstream "; $rrdcreate .= "DS:inblock:COUNTER:$packetsvalid:0:$downstream "; $rrdcreate .= "DS:outblock:COUNTER:$packetsvalid:0:$upstream "; + $rrdcreate .= "DS:inpass6:COUNTER:$packetsvalid:0:$downstream "; + $rrdcreate .= "DS:outpass6:COUNTER:$packetsvalid:0:$upstream "; + $rrdcreate .= "DS:inblock6:COUNTER:$packetsvalid:0:$downstream "; + $rrdcreate .= "DS:outblock6:COUNTER:$packetsvalid:0:$upstream "; $rrdcreate .= "RRA:AVERAGE:0.5:1:1000 "; $rrdcreate .= "RRA:AVERAGE:0.5:5:1000 "; $rrdcreate .= "RRA:AVERAGE:0.5:60:1000 "; @@ -323,16 +331,16 @@ function enable_rrd_graphing() { /* enter UNKNOWN values in the RRD so it knows we rebooted. */ if($g['booting']) { - mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U"); + mwexec("$rrdtool update $rrddbpath$ifname$packets N:U:U:U:U:U:U:U:U"); } $rrdupdatesh .= "\n"; $rrdupdatesh .= "# polling packets for interface $ifname $realif \n"; - $rrdupdatesh .= "unset PACKETS \n"; - $rrdupdatesh .= "PACKETS=`cat \$TMPFILE | awk '/In4\/Pass|Out4\/Pass/ {printf \$4 \":\"}'`\\\n"; - $rrdupdatesh .= "`cat \$TMPFILE | awk '/In4\/Block|Out4\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\n"; - $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\$PACKETS\n"; - $rrdupdatesh .= "rm \$TMPFILE \n"; + $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:"; + $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '\\\n"; + $rrdupdatesh .= "/In4\/Pass/ { b4pi = \$4 };/Out4\/Pass/ { b4po = \$4 };/In4\/Block/ { b4bi = \$4 };/Out4\/Block/ { b4bo = \$4 };\\\n"; + $rrdupdatesh .= "/In6\/Pass/ { b6pi = \$4 };/Out6\/Pass/ { b6po = \$4 };/In6\/Block/ { b6bi = \$4 };/Out6\/Block/ { b6bo = \$4 };\\\n"; + $rrdupdatesh .= "END {print b4pi \":\" b4po \":\" b4bi \":\" b4bo \":\" b6pi \":\" b6po \":\" b6bi \":\" b6bo};'`\n"; /* WIRELESS, set up the rrd file */ if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") { diff --git a/etc/inc/services.inc b/etc/inc/services.inc index d5c9ada..382e8dd 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -35,36 +35,124 @@ pfSense_BUILDER_BINARIES: /usr/bin/killall /bin/pgrep /bin/sh /usr/local/sbin/dhcpd /usr/local/sbin/igmpproxy pfSense_BUILDER_BINARIES: /sbin/ifconfig /usr/sbin/arp /sbin/ifconfig /usr/local/sbin/dnsmasq pfSense_BUILDER_BINARIES: /usr/sbin/bsnmpd /sbin/route /usr/local/sbin/olsrd - pfSense_BUILDER_BINARIES: /usr/local/sbin/miniupnpd + pfSense_BUILDER_BINARIES: /usr/local/sbin/miniupnpd /usr/sbin/rtadvd pfSense_MODULE: utils */ -function services_dhcpd_configure() { +/* implement ipv6 route advertising deamon */ +function services_rtadvd_configure() { global $config, $g; - if($g['services_dhcp_server_enable'] == false) - return; - if(isset($config['system']['developerspew'])) { $mt = microtime(); - echo "services_dhcpd_configure($if) being called $mt\n"; + echo "services_rtadvd_configure() being called $mt\n"; } - - /* kill any running dhcpd */ - if(is_process_running("dhcpd")) - mwexec("killall dhcpd", true); - /* DHCP enabled on any interfaces? */ - if (!is_dhcp_server_enabled()) - return 0; + if(is_process_running("rtadvd")) { + mwexec("killall -9 rtadvd", true); + } - /* if OLSRD is enabled, allow WAN to house DHCP. */ - if($config['installedpackages']['olsrd']) - foreach($config['installedpackages']['olsrd']['config'] as $olsrd) - if($olsrd['enable']) - $is_olsr_enabled = true; + if (!is_array($config['dhcpdv6'])) + $config['dhcpdv6'] = array(); + + $dhcpdv6cfg = $config['dhcpdv6']; + $Iflist = get_configured_interface_list(); + + /* write rtadvd.conf */ + $fd = fopen("{$g['varetc_path']}/rtadvd.conf", "w"); + if (!$fd) { + printf("Error: cannot open rtadvd.conf in services_rtadvd_configure().\n"); + return 1; + } + + /* raflags, other o, managed=64 m, stateful=128, both=192 */ + + $rtadvdconf = "# Automatically Generated, do not edit\n"; + $rtadvdconf = <<<EOD + +# +# common definitions. +# +default:\ + :raflags#0:rltime#3600:\ + :vltime#360000:pltime#360000:mtu#1500: +ether:\ + :mtu#1280:tc=default: + +EOD; + + /* Process all links which need the router advertise daemon */ + $rtadvdnum = 0; + foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + if($dhcpv6ifconf['mode'] == "disabled") + continue; + + $realif = get_real_interface($dhcpv6if); + $rtadvdifs[] = $realif; + + $ifcfgipv6 = get_interface_ipv6($dhcpv6if); + $ifcfgsnv6 = get_interface_subnetv6($dhcpv6if); + $subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6); + $subnetmaskv6 = gen_subnet_mask($ifcfgsnv6); + + $rtadvdconf .= "# Generated for DHCPv6 Server $dhcpv6if\n"; + $rtadvdconf .= "{$realif}:\\\n"; + $rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n"; + $rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n"; + switch($dhcpv6ifconf['mode']) { + case "managed": + $rtadvdconf .= "\t:raflags=\"m\":\\\n"; + break; + case "assist": + $rtadvdconf .= "\t:raflags=\"mo\":\\\n"; + break; + default: + $rtadvdconf .= "\t:raflags#0:\\\n"; + break; - /* configure DHCPD chroot */ + } + $rtadvdconf .= "\t:tc=ether:\n"; + $rtadvdconf .= "\n\n"; + $rtadvdnum++; + } + + foreach ($Iflist as $if => $ifdescr) { + if(!is_numeric($config['interfaces'][$if]['dhcp6-pd-sla-id'])) + continue; + + $realif = get_real_interface($if); + $rtadvdifs[] = $realif; + + $ifcfgipv6 = get_interface_ipv6($if); + $ifcfgsnv6 = get_interface_subnetv6($if); + $subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6); + $subnetmaskv6 = gen_subnet_mask($ifcfgsnv6); + + if(is_ipaddrv6($subnetv6)) { + $rtadvdconf .= "# Generated for DHCP-PD delegation $if\n"; + $rtadvdconf .= "{$realif}:\\\n"; + $rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n"; + $rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n"; + $rtadvdconf .= "\t:raflags=\"mo\":\\\n"; + $rtadvdconf .= "\t:tc=ether:\n"; + $rtadvdconf .= "\n\n"; + $rtadvdnum++; + } + } + + fwrite($fd, $rtadvdconf); + fclose($fd); + + if(count($rtadvdifs) > 0) { + mwexec("/usr/sbin/rtadvd -c {$g['varetc_path']}/rtadvd.conf " . join(" ", $rtadvdifs)); + } + return 0; +} + +function services_dhcpd_configure() { + global $config, $g; + + /* configure DHCPD chroot once */ $fd = fopen("{$g['tmp_path']}/dhcpd.sh","w"); $status = `mount | grep "{$g['dhcpd_chroot_path']}/dev"`; fwrite($fd, "mkdir -p {$g['dhcpd_chroot_path']}\n"); @@ -85,6 +173,38 @@ function services_dhcpd_configure() { fclose($fd); mwexec("/bin/sh {$g['tmp_path']}/dhcpd.sh"); + services_dhcpdv4_configure(); + services_dhcpdv6_configure(); + services_rtadvd_configure(); + return; + +} +function services_dhcpdv4_configure() { + global $config, $g; + + if($g['services_dhcp_server_enable'] == false) + return; + + if(isset($config['system']['developerspew'])) { + $mt = microtime(); + echo "services_dhcpdv4_configure($if) being called $mt\n"; + } + + /* kill any running dhcpd */ + if(is_process_running("dhcpd")) { + killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpd.pid"); + } + + /* DHCP enabled on any interfaces? */ + if (!is_dhcp_server_enabled()) + return 0; + + /* if OLSRD is enabled, allow WAN to house DHCP. */ + if($config['installedpackages']['olsrd']) + foreach($config['installedpackages']['olsrd']['config'] as $olsrd) + if($olsrd['enable']) + $is_olsr_enabled = true; + if ($g['booting']) { if ($g['platform'] != "pfSense") { /* restore the leases, if we have them */ @@ -101,6 +221,8 @@ function services_dhcpd_configure() { } $syscfg = $config['system']; + if (!is_array($config['dhcpd'])) + $config['dhcpd'] = array(); $dhcpdcfg = $config['dhcpd']; $Iflist = get_configured_interface_list(); @@ -112,7 +234,7 @@ function services_dhcpd_configure() { /* write dhcpd.conf */ $fd = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpd.conf", "w"); if (!$fd) { - printf("Error: cannot open dhcpd.conf in services_dhcpd_configure().\n"); + printf("Error: cannot open dhcpd.conf in services_dhcpdv4_configure().\n"); return 1; } @@ -294,8 +416,7 @@ EOPP; $dnscfg EOD; - - // default-lease-time + // default-lease-time if ($dhcpifconf['defaultleasetime']) $dhcpdconf .= " default-lease-time {$dhcpifconf['defaultleasetime']};\n"; @@ -382,12 +503,352 @@ EOD; /* create an empty leases database */ touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"); - touch("{$g['varrun_path']}/dhcpd.pid"); /* fire up dhcpd in a chroot */ - mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf " . - join(" ", $dhcpdifs)); + if(count($dhcpdifs) > 0) { + mwexec("/usr/local/sbin/dhcpd -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpd.conf -pf {$g['varrun_path']}/dhcpd.pid " . + join(" ", $dhcpdifs)); + } + + if ($g['booting']) { + print "done.\n"; + } + + return 0; +} + +function services_dhcpdv6_configure() { + global $config, $g; + + if($g['services_dhcp_server_enable'] == false) + return; + + if(isset($config['system']['developerspew'])) { + $mt = microtime(); + echo "services_dhcpd_configure($if) being called $mt\n"; + } + + /* kill any running dhcpd */ + if(is_process_running("dhcpd")) { + killbypid("{$g['dhcpd_chroot_path']}{$g['varrun_path']}/dhcpdv6.pid"); + } + + /* DHCP enabled on any interfaces? */ + if (!is_dhcp_server_enabled()) + return 0; + + /* if OLSRD is enabled, allow WAN to house DHCP. */ + if($config['installedpackages']['olsrd']) + foreach($config['installedpackages']['olsrd']['config'] as $olsrd) + if($olsrd['enable']) + $is_olsr_enabled = true; + + if ($g['booting']) { + if ($g['platform'] != "pfSense") { + /* restore the leases, if we have them */ + if (file_exists("{$g['cf_conf_path']}/dhcp6leases.tgz")) { + $dhcprestore = ""; + $dhcpreturn = ""; + exec("cd /;LANG=C /usr/bin/tar -xzf {$g['cf_conf_path']}/dhcp6leases.tgz 2>&1", $dhcprestore, $dhcpreturn); + $dhcprestore = implode(" ", $dhcprestore); + if($dhcpreturn <> 0) { + log_error("DHCP leases v6 restore failed exited with $dhcpreturn, the error is: $dhcprestore\n"); + } + } + } + } + + $syscfg = $config['system']; + if (!is_array($config['dhcpdv6'])) + $config['dhcpdv6'] = array(); + $dhcpdv6cfg = $config['dhcpdv6']; + $Iflist = get_configured_interface_list(); + + if ($g['booting']) + echo "Starting DHCPv6 service..."; + else + sleep(1); + + /* write dhcpdv6.conf */ + $fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w"); + if (! $fdv6) { + printf("Error: cannot open dhcpdv6.conf in services_dhcpdv6_configure().\n"); + return 1; + } + + $custoptionsv6 = ""; + foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + if(is_array($dhcpv6ifconf['numberoptions']) && is_array($dhcpv6ifconf['numberoptions']['item'])) { + foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) { + $custoptionsv6 .= "option custom-{$dhcpv6if}-{$itemv6idx} code {$itemv6['number']} = text;\n"; + } + } + } + + $dhcpdv6conf = <<<EOD + +option domain-name "{$syscfg['domain']}"; +option ldap-server code 95 = text; +option domain-search-list code 119 = text; +{$custoptions} +default-lease-time 7200; +max-lease-time 86400; +log-facility local7; +ddns-update-style none; +one-lease-per-client true; +deny duplicates; +ping-check true; + +EOD; + + if(!isset($dhcpv6ifconf['disableauthoritative'])) + $dhcpdv6conf .= "authoritative;\n"; + + if(isset($dhcpv6ifconf['alwaysbroadcast'])) + $dhcpdv6conf .= "always-broadcast on\n"; + + $dhcpdv6ifs = array(); + + /* loop through and determine if we need to setup + * failover peer "bleh" entries + */ + $dhcpv6num = 0; + foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + + if (!isset($dhcpv6ifconf['enable'])) + continue; + + if($dhcpv6ifconf['failover_peerip'] <> "") { + $intv6 = guess_interface_from_ip($dhcpv6ifconf['failover_peerip']); + $intipv6 = find_interface_ipv6($intv6); + $real_dhcpv6if = convert_friendly_interface_to_real_interface_name($dhcpv6if); + /* + * yep, failover peer is defined. + * does it match up to a defined vip? + */ + $skew = 110; + $a_vip = &$config['virtualip']['vip']; + if(is_array($a_vip)) { + foreach ($a_vip as $vipent) { + if($intv6 == $real_dhcpv6if) { + /* this is the interface! */ + if(is_numeric($vipent['advskew']) && ($vipent['advskew'] < "20")) + $skew = 0; + } + } + } else { + log_error("Warning! DHCPv6 Failover setup and no CARP virtual IPv6's defined!"); + } + if($skew > 10) { + $typev6 = "secondary"; + $dhcpdv6conf_pri = "mclt 600;\n"; + $my_portv6 = "520"; + $peer_portv6 = "519"; + } else { + $my_portv6 = "519"; + $peer_portv6 = "520"; + $typev6 = "primary"; + $dhcpdv6conf_pri = "split 128;\n"; + $dhcpdv6conf_pri .= " mclt 600;\n"; + } + $dhcpdv6conf .= <<<EOPP +failover peer "dhcpv6{$dhcpv6num}" { + {$typev6}; + address {$intipv6}; + port {$my_portv6}; + peer address {$dhcpv6ifconf['failover_peerip']}; + peer port {$peer_portv6}; + max-response-delay 10; + max-unacked-updates 10; + {$dhcpdv6conf_pri} + load balance max seconds 3; +} + +EOPP; + $dhcpv6num++; + } + } + + $dhcpv6num = 0; + foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + + $ifcfgv6 = $config['interfaces'][$dhcpv6if]; + + if (!isset($dhcpv6ifconf['enable']) || !isset($Iflist[$dhcpv6if])) + continue; + $ifcfgipv6 = get_interface_ipv6($dhcpv6if); + $ifcfgsnv6 = get_interface_subnetv6($dhcpv6if); + $subnetv6 = gen_subnetv6($ifcfgipv6, $ifcfgsnv6); + $subnetmaskv6 = gen_subnet_mask($ifcfgsnv6); + + if($is_olsr_enabled == true) + if($dhcpv6ifconf['netmask']) + $subnetmask = gen_subnet_maskv6($dhcpv6ifconf['netmask']); + + $dnscfgv6 = ""; + + if ($dhcpv6ifconf['domain']) { + $dnscfgv6 .= " option domain-name \"{$dhcpv6ifconf['domain']}\";\n"; + } + + if($dhcpv6ifconf['domainsearchlist'] <> "") { + $dnscfgv6 .= " option domain-search-list \"{$dhcpifconf['domainsearchlist']}\";\n"; + } + + if (isset($dhcpv6ifconf['ddnsupdate'])) { + if($dhcpv6ifconf['ddnsdomain'] <> "") { + $dnscfgv6 .= " ddns-domainname \"{$dhcpv6ifconf['ddnsdomain']}\";\n"; + } + $dnscfgv6 .= " ddns-update-style interim;\n"; + } + + if (is_array($dhcpv6ifconf['dnsserver']) && ($dhcpv6ifconf['dnsserver'][0])) { + $dnscfgv6 .= " option dhcp6.name-servers " . join(",", $dhcpv6ifconf['dnsserver']) . ";"; + } else if (isset($config['dnsmasq']['enable'])) { + $dnscfgv6 .= " option dhcp6.name-servers {$ifcfgipv6};"; + } else if (is_array($syscfg['dnsserver']) && ($syscfg['dnsserver'][0])) { + $dns_arrv6 = array(); + foreach($syscfg['dnsserver'] as $dnsserver) { + if(is_ipaddrv6($dnsserver)) { + $dns_arrv6[] = $dnsserver; + } + } + if(!empty($dns_arrv6)) + $dnscfgv6 .= " option dhcp6.name-servers " . join(",", $dns_arrv6) . ";"; + } + + $subnet6 = Net_IPv6::compress(gen_subnetv6($ifcfgipv6, $ifcfgsnv6)); + $dhcpdv6conf .= "subnet6 {$subnet6}/{$ifcfgsnv6} {\n"; + + /* is failover dns setup? */ + if (is_array($dhcpv6ifconf['dnsserver']) && $dhcpv6ifconf['dnsserver'][0] <> "") { + $dhcpdv6conf .= " option dhcp6.name-servers {$dhcpv6ifconf['dnsserver'][0]}"; + if($dhcpv6ifconf['dnsserver'][1] <> "") + $dhcpdv6conf .= ",{$dhcpv6ifconf['dnsserver'][1]}"; + $dhcpdv6conf .= ";\n"; + } + + if($dhcpv6ifconf['failover_peerip'] <> "") + $dhcpdv6conf .= " deny dynamic bootp clients;\n"; + + if (isset($dhcpv6ifconf['denyunknown'])) + $dhcpdv6conf .= " deny unknown clients;\n"; + + if ($dhcpv6ifconf['gateway']) + $routersv6 = $dhcpv6ifconf['gateway']; + else + $routersv6 = $ifcfgipv6; + + if($dhcpv6ifconf['failover_peerip'] <> "") { + $dhcpdv6conf .= " failover peer \"dhcpv6{$dhcpv6num}\";\n"; + $dhcpv6num++; + } + + $dhcpdv6conf .= <<<EOD + range6 {$dhcpv6ifconf['range']['from']} {$dhcpv6ifconf['range']['to']}; + # Not supported in IPv6; option dhcp6.routers {$routersv6}; +$dnscfgv6 + +EOD; + + if(is_ipaddrv6($dhcpv6ifconf['prefixrange']['from']) && is_ipaddrv6($dhcpv6ifconf['prefixrange']['to'])) { + $dhcpdv6conf .= " prefix6 {$dhcpv6ifconf['prefixrange']['from']} {$dhcpv6ifconf['prefixrange']['to']}/{$dhcpv6ifconf['prefixrange']['prefixlength']};\n"; + + } + // default-lease-time + if ($dhcpv6ifconf['defaultleasetime']) + $dhcpdv6conf .= " default-lease-time {$dhcpv6ifconf['defaultleasetime']};\n"; + + // max-lease-time + if ($dhcpv6ifconf['maxleasetime']) + $dhcpdv6conf .= " max-lease-time {$dhcpv6ifconf['maxleasetime']};\n"; + + // ntp-servers + if (is_array($dhcpv6ifconf['ntpserver']) && $dhcpv6ifconf['ntpserver'][0]) + $dhcpdv6conf .= " option ntp-servers " . join(",", $dhcpv6ifconf['ntpserver']) . ";\n"; + + // tftp-server-name + if ($dhcpv6ifconf['tftp'] <> "") + $dhcpdv6conf .= " option tftp-server-name \"{$dhcpv6ifconf['tftp']}\";\n"; + + // Handle option, number rowhelper values + $dhcpdv6conf .= "\n"; + if($dhcpv6ifconf['numberoptions']['item']) { + foreach($dhcpv6ifconf['numberoptions']['item'] as $itemv6idx => $itemv6) { + $dhcpdv6conf .= " option custom-{$dhcpv6if}-{$itemv6idx} \"{$itemv6['value']}\";\n"; + } + } + + // ldap-server + if ($dhcpv6ifconf['ldap'] <> "") + $dhcpdv6conf .= " option ldap-server \"{$dhcpv6ifconf['ldap']}\";\n"; + + // net boot information + if(isset($dhcpv6ifconf['netboot'])) { + if (($dhcpv6ifconf['next-server'] <> "") && ($dhcpv6ifconf['filename'] <> "")) { + $dhcpdv6conf .= " next-server {$dhcpv6ifconf['next-server']};\n"; + $dhcpdv6conf .= " filename \"{$dhcpv6ifconf['filename']}\";\n"; + } + if ($dhcpv6ifconf['rootpath'] <> "") { + $dhcpdv6conf .= " option root-path \"{$dhcpv6ifconf['rootpath']}\";\n"; + } + } + + $dhcpdv6conf .= <<<EOD +} +EOD; + + /* add static mappings */ + /* Needs to use DUID */ + if (is_array($dhcpv6ifconf['staticmap'])) { + + $i = 0; + foreach ($dhcpv6ifconf['staticmap'] as $sm) { + $dhcpdv6conf .= <<<EOD +host s_{$dhcpv6if}_{$i} { + host-identifier option dhcp6.client-id {$sm['duid']}; + +EOD; + if ($sm['ipaddrv6']) + $dhcpdv6conf .= " fixed-address6 {$sm['ipaddrv6']};\n"; + + if ($sm['hostname']) { + $dhhostname = str_replace(" ", "_", $sm['hostname']); + $dhhostname = str_replace(".", "_", $dhhostname); + $dhcpdv6conf .= " option host-name {$dhhostname};\n"; + } + if ($sm['netbootfile']) + $dhcpdv6conf .= " filename \"{$sm['netbootfile']}\";\n"; + + $dhcpdv6conf .= "}\n"; + $i++; + } + } + + if($config['dhcpdv6'][$dhcpv6if]['mode'] <> "unmanaged") { + $realif = escapeshellcmd(get_real_interface($dhcpv6if)); + $dhcpdv6ifs[] = $realif; + exec("/sbin/ifconfig {$realif} |awk '/ether/ {print $2}'", $mac); + $v6address = generate_ipv6_from_mac($mac[0]); + /* Create link local address for bridges */ + if(stristr("$realif", "bridge")) { + mwexec("/sbin/ifconfig {$realif} inet6 {$v6address}"); + } + } + } + + fwrite($fdv6, $dhcpdv6conf); + fclose($fdv6); + /* create an empty leases v6 database */ + touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases"); + + + /* fire up dhcpd in a chroot */ + if(count($dhcpdv6ifs) > 0) { + mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf -pf {$g['varrun_path']}/dhcpdv6.pid " . + join(" ", $dhcpdv6ifs)); + } if ($g['booting']) { print "done.\n"; @@ -613,6 +1074,7 @@ function services_dyndns_configure_client($conf) { $dnsWilcard = $conf['wildcard'], $dnsMX = $conf['mx'], $dnsIf = "{$conf['interface']}"); + } function services_dyndns_configure($int = "") { diff --git a/etc/inc/system.inc b/etc/inc/system.inc index 72b2e0d..a2f0598 100644 --- a/etc/inc/system.inc +++ b/etc/inc/system.inc @@ -322,14 +322,20 @@ function system_routing_configure($interface = "") { echo "system_routing_configure() being called $mt\n"; } + /* configure gif interfaces for ipv6 tunnels */ + // interfaces_gif_configure(); + $gatewayip = ""; $interfacegw = ""; $foundgw = false; + $gatewayipv6 = ""; + $interfacegwv6 = ""; + $foundgwv6 = false; /* tack on all the hard defined gateways as well */ if (is_array($config['gateways']['gateway_item'])) { mwexec("/bin/rm {$g['tmp_path']}/*_defaultgw", true); foreach ($config['gateways']['gateway_item'] as $gateway) { - if (isset($gateway['defaultgw'])) { + if (isset($gateway['defaultgw']) && (is_ipaddrv4($gateway['gateway']))) { if(strstr($gateway['gateway'], ":")) break; if ($gateway['gateway'] == "dynamic") @@ -345,6 +351,21 @@ function system_routing_configure($interface = "") { break; } } + foreach ($config['gateways']['gateway_item'] as $gateway) { + if (isset($gateway['defaultgw']) && (is_ipaddrv6($gateway['gateway']))) { + if ($gateway['gateway'] == "dynamic") + $gateway['gateway'] = get_interface_gateway_v6($gateway['interface']); + $gatewayipv6 = $gateway['gateway']; + $interfacegwv6 = $gateway['interface']; + if (!empty($interfacegwv6)) { + $defaultifv6 = get_real_interface($gateway['interface']); + if ($defaultifv6) + @file_put_contents("{$g['tmp_path']}/{$defaultifv6}_defaultgwv6", $gatewayipv6); + } + $foundgwv6 = true; + break; + } + } } if ($foundgw == false) { $defaultif = get_real_interface("wan"); @@ -352,6 +373,12 @@ function system_routing_configure($interface = "") { $gatewayip = get_interface_gateway("wan"); @touch("{$g['tmp_path']}/{$defaultif}_defaultgw"); } + if ($foundgwv6 == false) { + $defaultifv6 = get_real_interface("wan"); + $interfacegwv6 = "wan"; + $gatewayipv6 = get_interface_gateway_v6("wan"); + @touch("{$g['tmp_path']}/{$defaultif}_defaultgwv6"); + } $dont_add_route = false; /* if OLSRD is enabled, allow WAN to house DHCP. */ if($config['installedpackages']['olsrd']) { @@ -362,7 +389,7 @@ function system_routing_configure($interface = "") { } } } - /* Create a array from the existing route table */ + /* Create a array from the existing inet route table */ exec("/usr/bin/netstat -rnf inet", $route_str); array_shift($route_str); array_shift($route_str); @@ -377,7 +404,7 @@ function system_routing_configure($interface = "") { if ($dont_add_route == false ) { if (!empty($interface) && $interface != $interfacegw) ; - else if (($interfacegw <> "bgpd") && (is_ipaddr($gatewayip))) { + else if (($interfacegw <> "bgpd") && (is_ipaddrv4($gatewayip))) { $action = "add"; if(isset($route_arr['default'])) { $action = "change"; @@ -387,6 +414,31 @@ function system_routing_configure($interface = "") { } } + /* Create a array from the existing inet6 route table */ + exec("/usr/bin/netstat -rnf inet6", $routev6_str); + array_shift($routev6_str); + array_shift($routev6_str); + array_shift($routev6_str); + array_shift($routev6_str); + $routev6_arr = array(); + foreach($routev6_str as $routeline) { + $items = preg_split("/[ ]+/i", $routeline); + $routev6_arr[$items[0]] = array($items[0], $items[1], $items[5]); + } + + if ($dont_add_route == false ) { + if (!empty($interface) && $interface != $interfacegwv6) + ; + else if (($interfacegwv6 <> "bgpd") && (is_ipaddrv6($gatewayipv6))) { + $action = "add"; + if(isset($routev6_arr['default'])) { + $action = "change"; + } + log_error("ROUTING: $action IPv6 default route to $gatewayipv6"); + mwexec("/sbin/route {$action} -inet6 default " . escapeshellarg($gatewayipv6)); + } + } + if (is_array($config['staticroutes']['route'])) { $gateways_arr = return_gateways_array(); @@ -399,17 +451,23 @@ function system_routing_configure($interface = "") { $gateway = $gateways_arr[$rtent['gateway']]; if (!empty($interface) && $interface != $gateway['friendlyiface']) continue; + $gatewayip = $gateway['gateway']; $interfacegw = $gateway['interface']; $action = "add"; if (isset($route_arr[$rtent['network']])) $action = "change"; + if(is_ipaddrv6($gatewayip)) { + $inetfamily = "-inet6"; + } else { + $inetfamily = "-inet"; + } if (is_ipaddr($gatewayip)) { - mwexec("/sbin/route {$action} -inet " . escapeshellarg($rtent['network']) . + mwexec("/sbin/route {$action} {$inetfamily} " . escapeshellarg($rtent['network']) . " " . escapeshellarg($gatewayip)); } else if (!empty($interfacegw)) { - mwexec("/sbin/route {$action} -inet " . escapeshellarg($rtent['network']) . + mwexec("/sbin/route {$action} {$inetfamily} " . escapeshellarg($rtent['network']) . " -iface " . escapeshellarg($interfacegw)); } } @@ -425,7 +483,9 @@ function system_routing_enable() { echo "system_routing_enable() being called $mt\n"; } - return mwexec("/sbin/sysctl net.inet.ip.forwarding=1"); + mwexec("/sbin/sysctl net.inet.ip.forwarding=1"); + mwexec("/sbin/sysctl net.inet6.ip6.forwarding=1"); + return; } function system_syslogd_start() { @@ -907,13 +967,14 @@ EOD; ## FreeBSD! server.event-handler = "freebsd-kqueue" server.network-backend = "writev" +#server.use-ipv6 = "enable" ## modules to load server.modules = ( - {$captive_portal_module} - "mod_access", "mod_accesslog", "mod_expire", "mod_compress", "mod_redirect", - {$module}{$captiveportal} - ) + {$captive_portal_module} + "mod_access", "mod_accesslog", "mod_expire", "mod_compress", "mod_redirect", + {$module}{$captiveportal} +) ## Unused modules # "mod_setenv", @@ -1020,7 +1081,41 @@ url.access-deny = ( "~", ".inc" ) ######### Options that are good to be but not neccesary to be changed ####### ## bind to port (default: 80) -server.port = {$lighty_port} + +EOD; + + if($captive_portal == true) { + $lighty_config .= "server.bind = \"127.0.0.1\"\n"; + $lighty_config .= "server.port = {$lighty_port}\n"; + $lighty_config .= "\$SERVER[\"socket\"] == \"127.0.0.1:{$lighty_port}\" { }\n"; + $lighty_config .= "\$SERVER[\"socket\"] == \"[::1]:{$lighty_port}\" { \n"; + if($cert <> "" and $key <> "") { + $lighty_config .= "\n"; + $lighty_config .= "## ssl configuration\n"; + $lighty_config .= "ssl.engine = \"enable\"\n"; + $lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n"; + if($ca <> "") + $lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n"; + } + $lighty_config .= " }\n"; + } else { + $lighty_config .= "server.bind = \"0.0.0.0\"\n"; + $lighty_config .= "server.port = {$lighty_port}\n"; + $lighty_config .= "\$SERVER[\"socket\"] == \"0.0.0.0:{$lighty_port}\" { }\n"; + $lighty_config .= "\$SERVER[\"socket\"] == \"[::]:{$lighty_port}\" { \n"; + if($cert <> "" and $key <> "") { + $lighty_config .= "\n"; + $lighty_config .= "## ssl configuration\n"; + $lighty_config .= "ssl.engine = \"enable\"\n"; + $lighty_config .= "ssl.pemfile = \"{$g['varetc_path']}/{$cert_location}\"\n\n"; + if($ca <> "") + $lighty_config .= "ssl.ca-file = \"{$g['varetc_path']}/{$ca_location}\"\n\n"; + } + $lighty_config .= " }\n"; + } + + + $lighty_config .= <<<EOD ## error-handler for status 404 #server.error-handler-404 = "/error-handler.html" diff --git a/etc/inc/upgrade_config.inc b/etc/inc/upgrade_config.inc index c380378..ccd5629 100644 --- a/etc/inc/upgrade_config.inc +++ b/etc/inc/upgrade_config.inc @@ -1917,7 +1917,7 @@ function upgrade_054_to_055() { $xmldumpnew = "{$database}.new.xml"; if ($g['booting']) - echo "Migrate RRD database {$database} to new format \n"; + echo "Migrate RRD database {$database} to new format for IPv6 \n"; mwexec("$rrdtool tune {$rrddbpath}{$database} -r roundtrip:delay 2>&1"); dump_rrd_to_xml("{$rrddbpath}/{$database}", "{$g['tmp_path']}/{$xmldump}"); @@ -2468,8 +2468,8 @@ function upgrade_075_to_076() { function upgrade_076_to_077() { global $config; foreach($config['filter']['rule'] as & $rule) { - if (isset($rule['protocol']) && !empty($rule['protocol'])) - $rule['protocol'] = strtolower($rule['protocol']); + if (isset($rule['protocol']) && !empty($rule['protocol'])) + $rule['protocol'] = strtolower($rule['protocol']); } } @@ -2490,11 +2490,102 @@ function upgrade_077_to_078() { $config['pptpd']['radius'] = $radarr; } } - function upgrade_078_to_079() { global $g; /* Delete old and unused RRD file */ unlink_if_exists("{$g['vardb_path']}/rrd/captiveportal-totalusers.rrd"); } +function upgrade_079_to_080() { + global $config; + global $g; + + /* RRD files changed for quality, traffic and packets graphs */ + /* convert traffic RRD file */ + global $parsedcfg, $listtags; + $listtags = array("ds", "v", "rra", "row"); + + $rrddbpath = "/var/db/rrd/"; + $rrdtool = "/usr/bin/nice -n20 /usr/local/bin/rrdtool"; + + $rrdinterval = 60; + $valid = $rrdinterval * 2; + + /* Asume GigE for now */ + $downstream = 125000000; + $upstream = 125000000; + + /* build a list of traffic and packets databases */ + $databases = array(); + exec("cd $rrddbpath;/usr/bin/find *-traffic.rrd *-packets.rrd", $databases); + rsort($databases); + foreach($databases as $database) { + $databasetmp = "{$database}.tmp"; + $xmldump = "{$database}.old.xml"; + $xmldumptmp = "{$database}.tmp.xml"; + $xmldumpnew = "{$database}.new.xml"; + + if ($g['booting']) + echo "Migrate RRD database {$database} to new format for IPv6.\n"; + + /* dump contents to xml and move database out of the way */ + dump_rrd_to_xml("{$rrddbpath}/{$database}", "{$g['tmp_path']}/{$xmldump}"); + + /* create new rrd database file */ + $rrdcreate = "$rrdtool create {$g['tmp_path']}/{$databasetmp} --step $rrdinterval "; + $rrdcreate .= "DS:inpass:COUNTER:$valid:0:$downstream "; + $rrdcreate .= "DS:outpass:COUNTER:$valid:0:$upstream "; + $rrdcreate .= "DS:inblock:COUNTER:$valid:0:$downstream "; + $rrdcreate .= "DS:outblock:COUNTER:$valid:0:$upstream "; + $rrdcreate .= "DS:inpass6:COUNTER:$valid:0:$downstream "; + $rrdcreate .= "DS:outpass6:COUNTER:$valid:0:$upstream "; + $rrdcreate .= "DS:inblock6:COUNTER:$valid:0:$downstream "; + $rrdcreate .= "DS:outblock6:COUNTER:$valid:0:$upstream "; + $rrdcreate .= "RRA:AVERAGE:0.5:1:1000 "; + $rrdcreate .= "RRA:AVERAGE:0.5:5:1000 "; + $rrdcreate .= "RRA:AVERAGE:0.5:60:1000 "; + $rrdcreate .= "RRA:AVERAGE:0.5:720:3000 "; + + create_new_rrd("$rrdcreate"); + /* create temporary xml from new RRD */ + dump_rrd_to_xml("{$g['tmp_path']}/{$databasetmp}", "{$g['tmp_path']}/{$xmldumptmp}"); + + $rrdoldxml = file_get_contents("{$g['tmp_path']}/{$xmldump}"); + $rrdold = xml2array($rrdoldxml, 1, "tag"); + $rrdold = $rrdold['rrd']; + + $rrdnewxml = file_get_contents("{$g['tmp_path']}/{$xmldumptmp}"); + $rrdnew = xml2array($rrdnewxml, 1, "tag"); + $rrdnew = $rrdnew['rrd']; + + /* remove any MAX RRA's. Not needed for traffic. */ + $i = 0; + foreach ($rrdold['rra'] as $rra) { + if(trim($rra['cf']) == "MAX") { + unset($rrdold['rra'][$i]); + } + $i++; + } + + $rrdxmlarray = migrate_rrd_format($rrdold, $rrdnew); + $rrdxml = dump_xml_config_raw($rrdxmlarray, "rrd"); + file_put_contents("{$g['tmp_path']}/{$xmldumpnew}", $rrdxml); + mwexec("$rrdtool restore -f {$g['tmp_path']}/{$xmldumpnew} {$rrddbpath}/{$database} 2>&1"); + + } + enable_rrd_graphing(); + if ($g['booting']) + echo "Updating configuration..."; + foreach($config['filter']['rule'] as & $rule) { + if (isset($rule['protocol']) && !empty($rule['protocol'])) + $rule['protocol'] = strtolower($rule['protocol']); + } +} + +function upgrade_080_to_081() { + global $config; + /* enable the allow IPv6 toggle */ + $config['system']['ipv6allow'] = true; +} + ?> diff --git a/etc/inc/util.inc b/etc/inc/util.inc index 7b8fc57..258700c 100644 --- a/etc/inc/util.inc +++ b/etc/inc/util.inc @@ -219,10 +219,18 @@ function is_module_loaded($module_name) { function gen_subnet($ipaddr, $bits) { if (!is_ipaddr($ipaddr) || !is_numeric($bits)) return ""; - return long2ip(ip2long($ipaddr) & gen_subnet_mask_long($bits)); } +/* return the subnet address given a host address and a subnet bit count */ +function gen_subnetv6($ipaddr, $bits) { + if (!is_ipaddrv6($ipaddr) || !is_numeric($bits)) + return ""; + + $address = Net_IPv6::getNetmask($ipaddr, $bits); + return $address; +} + /* return the highest (broadcast) address in the subnet given a host address and a subnet bit count */ function gen_subnet_max($ipaddr, $bits) { if (!is_ipaddr($ipaddr) || !is_numeric($bits)) @@ -231,6 +239,49 @@ function gen_subnet_max($ipaddr, $bits) { return long2ip32(ip2long($ipaddr) | ~gen_subnet_mask_long($bits)); } +/* Generate end number for a given ipv6 subnet mask + * no, it does not perform math */ +function gen_subnetv6_max($ipaddr, $bits) { + if(!is_ipaddrv6($ipaddr)) + return false; + + $subnetstart = gen_subnetv6($ipaddr, $bits); + /* we should have a expanded full ipv6 subnet starting at 0. + * Now split those by the semicolon so we can do 16 bit math */ + $parts = explode(":", $subnetstart); + if(count($parts) <> 8) + return false; + + /* reverse the array, we start with the lsb */ + $parts = array_reverse($parts); + /* set the itteration count properly */ + $bitsleft = 128 - $bits; + $i = 0; + foreach($parts as $part) { + /* foreach 16 bits we go to the next part */ + /* no this isn't proper hex math, neither does it overflow properly */ + while($bitsleft > 0) { + if($part == "0") { + $part = "f"; + } else { + $part = $part . "f"; + } + $bitsleft = $bitsleft - 4; + $j++; + if($j == 4) { + $parts[$i] = $part; + $j = 0; + $i++; + continue 2; + } + } + $i++; + } + $parts = array_reverse($parts); + $subnet_end = implode(":", $parts); + return $subnet_end; +} + /* returns a subnet mask (long given a bit count) */ function gen_subnet_mask_long($bits) { $sm = 0; @@ -381,8 +432,26 @@ function is_numericint($arg) { return (preg_match("/[^0-9]/", $arg) ? false : true); } -/* returns true if $ipaddr is a valid dotted IPv4 address */ + +/* returns true if $ipaddr is a valid dotted IPv4 address or a IPv6 */ function is_ipaddr($ipaddr) { + if(is_ipaddrv4($ipaddr)) { + return true; + } + if(is_ipaddrv6($ipaddr)) { + return true; + } + return false; +} + +/* returns true if $ipaddr is a valid IPv6 address */ +function is_ipaddrv6($ipaddr) { + $result = Net_IPv6::checkIPv6($ipaddr); + return $result; +} + +/* returns true if $ipaddr is a valid dotted IPv4 address */ +function is_ipaddrv4($ipaddr) { if (!is_string($ipaddr)) return false; @@ -951,6 +1020,13 @@ function ipcmp($a, $b) { /* return true if $addr is in $subnet, false if not */ function ip_in_subnet($addr,$subnet) { + if(is_ipaddrv6($addr)) { + $result = Net_IPv6::IsInNetmask($addr, $subnet); + if($result) + return true; + else + return false; + } list($ip, $mask) = explode('/', $subnet); $mask = (0xffffffff << (32 - $mask)) & 0xffffffff; return ((ip2long($addr) & $mask) == (ip2long($ip) & $mask)); @@ -1025,6 +1101,7 @@ function resolve_retry($hostname, $retries = 5) { return $hostname; for ($i = 0; $i < $retries; $i++) { + // FIXME: gethostbyname does not work for AAAA hostnames, boo, hiss $ip = gethostbyname($hostname); if ($ip && $ip != $hostname) { diff --git a/etc/inc/vpn.inc b/etc/inc/vpn.inc index 2411caf..819d396 100644 --- a/etc/inc/vpn.inc +++ b/etc/inc/vpn.inc @@ -138,12 +138,13 @@ function vpn_ipsec_configure($ipchg = false) $ipsecpinghosts = ""; /* step through each phase1 entry */ + $ipsecpinghosts = ""; foreach ($a_phase1 as $ph1ent) { if (isset($ph1ent['disabled'])) continue; $ep = ipsec_get_phase1_src($ph1ent); - if (!$ep) + if (!is_ipaddr($ep)) continue; if(!in_array($ep,$ipmap)) @@ -182,27 +183,43 @@ function vpn_ipsec_configure($ipchg = false) if ($ikeid != $ph1ent['ikeid']) continue; + $ph2ent['localid']['mode'] = $ph2ent['mode']; /* add an ipsec pinghosts entry */ if ($ph2ent['pinghost']) { $iflist = get_configured_interface_list(); foreach ($iflist as $ifent => $ifname) { - $interface_ip = get_interface_ip($ifent); - $local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true); - if (ip_in_subnet($interface_ip, $local_subnet)) { - $srcip = $interface_ip; - break; + if(is_ipaddrv6($ph2ent['pinghost'])) { + $interface_ip = get_interface_ipv6($ifent); + if(!is_ipaddrv6($interface_ip)) + continue; + $local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true); + if (ip_in_subnet($interface_ip, $local_subnet)) { + $srcip = $interface_ip; + break; + } + } else { + $interface_ip = get_interface_ip($ifent); + if(!is_ipaddrv4($interface_ip)) + continue; + $local_subnet = ipsec_idinfo_to_cidr($ph2ent['localid'], true); + if (ip_in_subnet($interface_ip, $local_subnet)) { + $srcip = $interface_ip; + break; + } } } $dstip = $ph2ent['pinghost']; + if(is_ipaddrv6($dstip)) { + $family = "inet6"; + } else { + $family = "inet"; + } if (is_ipaddr($srcip)) - $ipsecpinghosts .= "{$srcip}|{$dstip}|3\n"; + $ipsecpinghosts[] = "{$srcip}|{$dstip}|3|||||{$family}|\n"; + } } - $pfd = fopen("{$g['vardb_path']}/ipsecpinghosts", "w"); - if ($pfd) { - fwrite($pfd, $ipsecpinghosts); - fclose($pfd); - } + file_put_contents("{$g['vardb_path']}/ipsecpinghosts", $ipsecpinghosts); } } @@ -437,7 +454,7 @@ function vpn_ipsec_configure($ipchg = false) case "dyn_dns": $myid_type = "address"; - $myid_data = gethostbyname($ph1ent['myid_data']); + $myid_data = resolve_retry($ph1ent['myid_data']); break; case "address"; @@ -637,9 +654,10 @@ EOD; if (isset($ph2ent['mobile']) && !isset($a_client['enable'])) continue; - if ($ph2ent['mode'] == 'tunnel') { + if (($ph2ent['mode'] == 'tunnel') or ($ph2ent['mode'] == 'tunnel6')) { $localid_type = $ph2ent['localid']['type']; + $ph2ent['localid']['mode'] = $ph2ent['mode']; $localid_data = ipsec_idinfo_to_cidr($ph2ent['localid']); /* Do not print localid in some cases, such as a pure-psk or psk/xauth single phase2 mobile tunnel */ if (($localid_type == "none") || @@ -791,11 +809,18 @@ EOD; /* Try to prevent people from locking themselves out of webgui. Just in case. */ if ($config['interfaces']['lan']) { $lanip = get_interface_ip("lan"); - if (!empty($lanip) && is_ipaddr($lanip)) { + if (!empty($lanip) && is_ipaddrv4($lanip)) { $lansn = get_interface_subnet("lan"); $lansa = gen_subnet($lanip, $lansn); - $spdconf .= "spdadd {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n"; - $spdconf .= "spdadd {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n"; + $spdconf .= "spdadd -4 {$lanip}/32 {$lansa}/{$lansn} any -P out none;\n"; + $spdconf .= "spdadd -4 {$lansa}/{$lansn} {$lanip}/32 any -P in none;\n"; + } + $lanipv6 = get_interface_ipv6("lan"); + if (!empty($lanipv6) && is_ipaddrv6($lanipv6)) { + $lansnv6 = get_interface_subnetv6("lan"); + $lansav6 = gen_subnetv6($lanipv6, $lansnv6); + $spdconf .= "spdadd -6 {$lanipv6}/128 {$lansav6}/{$lansnv6} any -P out none;\n"; + $spdconf .= "spdadd -6 {$lansav6}/{$lansnv6} {$lanipv6}/128 any -P in none;\n"; } } @@ -821,15 +846,20 @@ EOD; if(!is_ipaddr($rgip)) continue; + $ph2ent['localid']['mode'] = $ph2ent['mode']; $localid = ipsec_idinfo_to_cidr($ph2ent['localid'],true); $remoteid = ipsec_idinfo_to_cidr($ph2ent['remoteid'],true); - if($ph2ent['mode'] == "tunnel") { + if(($ph2ent['mode'] == "tunnel") or ($ph2ent['mode'] == 'tunnel6')) { + if($ph2ent['mode'] == "tunnel6") + $family = "-6"; + else + $family = "-4"; - $spdconf .= "spdadd {$localid} {$remoteid} any -P out ipsec " . + $spdconf .= "spdadd {$family} {$localid} {$remoteid} any -P out ipsec " . "{$ph2ent['protocol']}/tunnel/{$ep}-{$rgip}/unique;\n"; - $spdconf .= "spdadd {$remoteid} {$localid} any -P in ipsec " . + $spdconf .= "spdadd {$family} {$remoteid} {$localid} any -P in ipsec " . "{$ph2ent['protocol']}/tunnel/{$rgip}-{$ep}/unique;\n"; } else { @@ -1673,6 +1703,7 @@ function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) { $sad_arr = ipsec_dump_sad(); $ep = ipsec_get_phase1_src($phase1); + $phase2['localid']['mode'] = $phase2['mode']; $local_subnet = ipsec_idinfo_to_cidr($phase2['localid']); $remote_subnet = ipsec_idinfo_to_cidr($phase2['remoteid']); @@ -1680,6 +1711,7 @@ function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) { $old_gw = trim($old_phase1['remote-gateway']); $old_ep = ipsec_get_phase1_src($old_phase1); + $old_phase2['localid']['mode'] = $old_phase2['mode']; $old_local_subnet = ipsec_idinfo_to_cidr($old_phase2['localid']); $old_remote_subnet = ipsec_idinfo_to_cidr($old_phase2['remoteid']); @@ -1715,11 +1747,16 @@ function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) { $spdconf = ""; /* Delete old SPD policies if there are changes between the old and new */ if(($phase1 != $old_phase1) || ($phase2 != $old_phase2)) { - $spdconf .= "spddelete {$old_local_subnet} " . + if($old_phase2['mode'] == "tunnel6") + $family = "-6"; + else + $family = "-4"; + + $spdconf .= "spddelete {$family} {$old_local_subnet} " . "{$old_remote_subnet} any -P out ipsec " . "{$old_phase2['protocol']}/tunnel/{$old_ep}-" . "{$old_gw}/unique;\n"; - $spdconf .= "spddelete {$old_remote_subnet} " . + $spdconf .= "spddelete {$family} {$old_remote_subnet} " . "{$old_local_subnet} any -P in ipsec " . "{$old_phase2['protocol']}/tunnel/{$old_gw}-" . "{$old_ep}/unique;\n"; @@ -1727,30 +1764,35 @@ function reload_tunnel_spd_policy($phase1, $phase2, $old_phase1, $old_phase2) { /* zap any existing SA entries */ foreach($sad_arr as $sad) { if(($sad['dst'] == $old_ep) && ($sad['src'] == $old_gw)) { - $spdconf .= "delete {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n"; + $spdconf .= "delete {$family} {$old_ep} {$old_gw} {$old_phase2['protocol']} 0x{$sad['spi']};\n"; } if(($sad['src'] == $oldep) && ($sad['dst'] == $old_gw)) { - $spdconf .= "delete {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n"; + $spdconf .= "delete {$family} {$old_gw} {$old_ep} {$old_phase2['protocol']} 0x{$sad['spi']};\n"; } } } + if($phase2['mode'] == "tunnel6") + $family = "-6"; + else + $family = "-4"; + /* Create new SPD entries for the new configuration */ /* zap any existing SA entries beforehand */ foreach($sad_arr as $sad) { if(($sad['dst'] == $ep) && ($sad['src'] == $rgip)) { - $spdconf .= "delete {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n"; + $spdconf .= "delete {$family} {$rgip} {$ep} {$phase2['protocol']} 0x{$sad['spi']};\n"; } if(($sad['src'] == $ep) && ($sad['dst'] == $rgip)) { - $spdconf .= "delete {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n"; + $spdconf .= "delete {$family} {$ep} {$rgip} {$phase2['protocol']} 0x{$sad['spi']};\n"; } } /* add new SPD policies to replace them */ - $spdconf .= "spdadd {$local_subnet} " . + $spdconf .= "spdadd {$family} {$local_subnet} " . "{$remote_subnet} any -P out ipsec " . "{$phase2['protocol']}/tunnel/{$ep}-" . "{$rgip}/unique;\n"; - $spdconf .= "spdadd {$remote_subnet} " . + $spdconf .= "spdadd {$family} {$remote_subnet} " . "{$local_subnet} any -P in ipsec " . "{$phase2['protocol']}/tunnel/{$rgip}-" . "{$ep}/unique;\n"; diff --git a/etc/inc/xmlrpc_client.inc b/etc/inc/xmlrpc_client.inc index 8b8a9a2..39d6d70 100644 --- a/etc/inc/xmlrpc_client.inc +++ b/etc/inc/xmlrpc_client.inc @@ -10,35 +10,18 @@ * * PHP versions 4 and 5 * - * LICENSE: License is granted to use or modify this software - * ("XML-RPC for PHP") for commercial or non-commercial use provided the - * copyright of the author is preserved in any distributed or derivative work. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * * @category Web Services * @package XML_RPC * @author Edd Dumbill <edd@usefulinc.com> * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version CVS: $Id$ + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version SVN: $Id: RPC.php 300961 2010-07-03 02:17:34Z danielc $ * @link http://pear.php.net/package/XML_RPC */ -/* - pfSense_MODULE: utils -*/ if (!function_exists('xml_parser_create')) { include_once 'PEAR.inc'; @@ -202,27 +185,6 @@ $GLOBALS['XML_RPC_errxml'] = 100; $GLOBALS['XML_RPC_backslash'] = chr(92) . chr(92); -/**#@+ - * Which functions to use, depending on whether mbstring is enabled or not. - */ -if (function_exists('mb_ereg')) { - /** @global string $GLOBALS['XML_RPC_func_ereg'] */ - $GLOBALS['XML_RPC_func_ereg'] = 'mb_eregi'; - /** @global string $GLOBALS['XML_RPC_func_ereg_replace'] */ - $GLOBALS['XML_RPC_func_ereg_replace'] = 'mb_eregi_replace'; - /** @global string $GLOBALS['XML_RPC_func_split'] */ - $GLOBALS['XML_RPC_func_split'] = 'mb_split'; -} else { - /** @ignore */ - $GLOBALS['XML_RPC_func_ereg'] = 'eregi'; - /** @ignore */ - $GLOBALS['XML_RPC_func_ereg_replace'] = 'eregi_replace'; - /** @ignore */ - $GLOBALS['XML_RPC_func_split'] = 'split'; -} -/**#@-*/ - - /** * Should we automatically base64 encode strings that contain characters * which can cause PHP's SAX-based XML parser to break? @@ -301,7 +263,7 @@ function XML_RPC_se($parser_resource, $name, $attrs) } else { // not top level element: see if parent is OK if (!in_array($XML_RPC_xh[$parser]['stack'][0], $XML_RPC_valid_parents[$name])) { - $name = $GLOBALS['XML_RPC_func_ereg_replace']('[^a-zA-Z0-9._-]', '', $name); + $name = preg_replace('@[^a-zA-Z0-9._-]@', '', $name); $XML_RPC_xh[$parser]['isf'] = 2; $XML_RPC_xh[$parser]['isf_reason'] = "xmlrpc element $name cannot be child of {$XML_RPC_xh[$parser]['stack'][0]}"; return; @@ -465,7 +427,7 @@ function XML_RPC_ee($parser_resource, $name) } else { // we have an I4, INT or a DOUBLE // we must check that only 0123456789-.<space> are characters here - if (!$GLOBALS['XML_RPC_func_ereg']("^[+-]?[0123456789 \t\.]+$", $XML_RPC_xh[$parser]['ac'])) { + if (!preg_match("@^[+-]?[0123456789 \t\.]+$@", $XML_RPC_xh[$parser]['ac'])) { XML_RPC_Base::raiseError('Non-numeric value received in INT or DOUBLE', XML_RPC_ERROR_NON_NUMERIC_FOUND); $XML_RPC_xh[$parser]['value'] = XML_RPC_ERROR_NON_NUMERIC_FOUND; @@ -529,7 +491,7 @@ function XML_RPC_ee($parser_resource, $name) case 'METHODNAME': case 'RPCMETHODNAME': - $XML_RPC_xh[$parser]['method'] = $GLOBALS['XML_RPC_func_ereg_replace']("^[\n\r\t ]+", '', + $XML_RPC_xh[$parser]['method'] = preg_replace("@^[\n\r\t ]+@", '', $XML_RPC_xh[$parser]['ac']); break; } @@ -581,8 +543,9 @@ function XML_RPC_cd($parser_resource, $data) * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version Release: 1.5.1 + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Base { @@ -626,8 +589,9 @@ class XML_RPC_Base { * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version Release: 1.5.1 + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Client extends XML_RPC_Base { @@ -765,7 +729,7 @@ class XML_RPC_Client extends XML_RPC_Base { $this->proxy_user = $proxy_user; $this->proxy_pass = $proxy_pass; - $GLOBALS['XML_RPC_func_ereg']('^(http://|https://|ssl://)?(.*)$', $server, $match); + preg_match('@^(http://|https://|ssl://)?(.*)$@', $server, $match); if ($match[1] == '') { if ($port == 443) { $this->server = $match[2]; @@ -793,7 +757,7 @@ class XML_RPC_Client extends XML_RPC_Base { } if ($proxy) { - $GLOBALS['XML_RPC_func_ereg']('^(http://|https://|ssl://)?(.*)$', $proxy, $match); + preg_match('@^(http://|https://|ssl://)?(.*)$@', $proxy, $match); if ($match[1] == '') { if ($proxy_port == 443) { $this->proxy = $match[2]; @@ -923,6 +887,26 @@ class XML_RPC_Client extends XML_RPC_Base { function sendPayloadHTTP10($msg, $server, $port, $timeout = 0, $username = '', $password = '') { + // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly + if ($username != $this->username) { + $this->setCredentials($username, $password); + } + + // Only create the payload if it was not created previously + if (empty($msg->payload)) { + $msg->createPayload(); + } + $this->createHeaders($msg); + + $op = $this->headers . "\r\n\r\n"; + $op .= $msg->payload; + + if ($this->debug) { + print "\n<pre>---SENT---\n"; + print $op; + print "\n---END---</pre>\n"; + } + /* * If we're using a proxy open a socket to the proxy server * instead to the xml-rpc server @@ -981,20 +965,6 @@ class XML_RPC_Client extends XML_RPC_Base { socket_set_timeout($fp, $timeout); } - // Pre-emptive BC hacks for fools calling sendPayloadHTTP10() directly - if ($username != $this->username) { - $this->setCredentials($username, $password); - } - - // Only create the payload if it was not created previously - if (empty($msg->payload)) { - $msg->createPayload(); - } - $this->createHeaders($msg); - - $op = $this->headers . "\r\n\r\n"; - $op .= $msg->payload; - if (!fputs($fp, $op, strlen($op))) { $this->errstr = 'Write error'; return 0; @@ -1068,8 +1038,9 @@ class XML_RPC_Client extends XML_RPC_Base { * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version Release: 1.5.1 + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Response extends XML_RPC_Base @@ -1159,8 +1130,9 @@ class XML_RPC_Response extends XML_RPC_Base * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version Release: 1.5.1 + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Message extends XML_RPC_Base @@ -1297,9 +1269,9 @@ class XML_RPC_Message extends XML_RPC_Base $this->payload .= "</params>\n"; $this->payload .= $this->xml_footer(); if ($this->remove_extra_lines) { - $this->payload = $GLOBALS['XML_RPC_func_ereg_replace']("[\r\n]+", "\r\n", $this->payload); + $this->payload = preg_replace("@[\r\n]+@", "\r\n", $this->payload); } else { - $this->payload = $GLOBALS['XML_RPC_func_ereg_replace']("\r\n|\n|\r|\n\r", "\r\n", $this->payload); + $this->payload = preg_replace("@\r\n|\n|\r|\n\r@", "\r\n", $this->payload); } if ($this->convert_payload_encoding) { $this->payload = mb_convert_encoding($this->payload, $this->send_encoding); @@ -1421,7 +1393,7 @@ class XML_RPC_Message extends XML_RPC_Base { global $XML_RPC_defencoding; - if ($GLOBALS['XML_RPC_func_ereg']('<\?xml[^>]*[:space:]*encoding[:space:]*=[:space:]*[\'"]([^"\']*)[\'"]', + if (preg_match('@<\?xml[^>]*\s*encoding\s*=\s*[\'"]([^"\']*)[\'"]@', $data, $match)) { $match[1] = trim(strtoupper($match[1])); @@ -1486,9 +1458,9 @@ class XML_RPC_Message extends XML_RPC_Base // See if response is a 200 or a 100 then a 200, else raise error. // But only do this if we're using the HTTP protocol. - if ($GLOBALS['XML_RPC_func_ereg']('^HTTP', $data) && - !$GLOBALS['XML_RPC_func_ereg']('^HTTP/[0-9\.]+ 200 ', $data) && - !$GLOBALS['XML_RPC_func_ereg']('^HTTP/[0-9\.]+ 10[0-9]([A-Z ]+)?[\r\n]+HTTP/[0-9\.]+ 200', $data)) + if (preg_match('@^HTTP@', $data) && + !preg_match('@^HTTP/[0-9\.]+ 200 @', $data) && + !preg_match('@^HTTP/[0-9\.]+ 10[0-9]([A-Z ]+)?[\r\n]+HTTP/[0-9\.]+ 200@', $data)) { $errstr = substr($data, 0, strpos($data, "\n") - 1); error_log('HTTP error, got response: ' . $errstr); @@ -1558,7 +1530,7 @@ class XML_RPC_Message extends XML_RPC_Base $r = new XML_RPC_Response($v); } } - $r->hdrs = split("\r?\n", $XML_RPC_xh[$parser]['ha'][1]); + $r->hdrs = preg_split("@\r?\n@", $XML_RPC_xh[$parser]['ha'][1]); return $r; } } @@ -1572,8 +1544,9 @@ class XML_RPC_Message extends XML_RPC_Base * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version Release: 1.5.1 + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Value extends XML_RPC_Base @@ -1731,7 +1704,7 @@ class XML_RPC_Value extends XML_RPC_Base $rs .= "<struct>\n"; reset($val); foreach ($val as $key2 => $val2) { - $rs .= "<member><name>${key2}</name>\n"; + $rs .= "<member><name>" . htmlspecialchars($key2) . "</name>\n"; $rs .= $this->serializeval($val2); $rs .= "</member>\n"; } @@ -1741,8 +1714,8 @@ class XML_RPC_Value extends XML_RPC_Base case 2: // array $rs .= "<array>\n<data>\n"; - for ($i = 0; $i < sizeof($val); $i++) { - $rs .= $this->serializeval($val[$i]); + foreach ($val as $value) { + $rs .= $this->serializeval($value); } $rs .= "</data>\n</array>"; break; @@ -1953,7 +1926,7 @@ function XML_RPC_iso8601_encode($timet, $utc = 0) function XML_RPC_iso8601_decode($idate, $utc = 0) { $t = 0; - if ($GLOBALS['XML_RPC_func_ereg']('([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})', $idate, $regs)) { + if (preg_match('@([0-9]{4})([0-9]{2})([0-9]{2})T([0-9]{2}):([0-9]{2}):([0-9]{2})@', $idate, $regs)) { if ($utc) { $t = gmmktime($regs[4], $regs[5], $regs[6], $regs[2], $regs[3], $regs[1]); } else { @@ -2042,10 +2015,10 @@ function XML_RPC_encode($php_val) case 'string': case 'NULL': - if ($GLOBALS['XML_RPC_func_ereg']('^[0-9]{8}\T{1}[0-9]{2}\:[0-9]{2}\:[0-9]{2}$', $php_val)) { + if (preg_match('@^[0-9]{8}\T{1}[0-9]{2}\:[0-9]{2}\:[0-9]{2}$@', $php_val)) { $XML_RPC_val->addScalar($php_val, $GLOBALS['XML_RPC_DateTime']); } elseif ($GLOBALS['XML_RPC_auto_base64'] - && $GLOBALS['XML_RPC_func_ereg']("[^ -~\t\r\n]", $php_val)) + && preg_match("@[^ -~\t\r\n]@", $php_val)) { // Characters other than alpha-numeric, punctuation, SP, TAB, // LF and CR break the XML parser, encode value via Base 64. diff --git a/etc/inc/xmlrpc_server.inc b/etc/inc/xmlrpc_server.inc index 8887bdf..a8e6ae3 100644 --- a/etc/inc/xmlrpc_server.inc +++ b/etc/inc/xmlrpc_server.inc @@ -10,35 +10,18 @@ * * PHP versions 4 and 5 * - * LICENSE: License is granted to use or modify this software - * ("XML-RPC for PHP") for commercial or non-commercial use provided the - * copyright of the author is preserved in any distributed or derivative work. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR "AS IS" AND ANY EXPRESSED OR - * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES - * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. - * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, - * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT - * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, - * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY - * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT - * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF - * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * * @category Web Services * @package XML_RPC * @author Edd Dumbill <edd@usefulinc.com> * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version CVS: $Id$ + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version SVN: $Id: Server.php 300961 2010-07-03 02:17:34Z danielc $ * @link http://pear.php.net/package/XML_RPC */ -/* - pfSense_MODULE: utils -*/ /** * Pull in the XML_RPC class @@ -272,8 +255,9 @@ function XML_RPC_Server_debugmsg($m) * @author Stig Bakken <stig@php.net> * @author Martin Jansen <mj@php.net> * @author Daniel Convissor <danielc@php.net> - * @copyright 1999-2001 Edd Dumbill, 2001-2006 The PHP Group - * @version Release: 1.5.1 + * @copyright 1999-2001 Edd Dumbill, 2001-2010 The PHP Group + * @license http://www.php.net/license/3_01.txt PHP License + * @version Release: @package_version@ * @link http://pear.php.net/package/XML_RPC */ class XML_RPC_Server @@ -377,7 +361,7 @@ class XML_RPC_Server if ($XML_RPC_Server_debuginfo != '') { return "<!-- PEAR XML_RPC SERVER DEBUG INFO:\n\n" - . $GLOBALS['XML_RPC_func_ereg_replace']('--', '- - ', $XML_RPC_Server_debuginfo) + . str_replace('--', '- - ', $XML_RPC_Server_debuginfo) . "-->\n"; } else { return ''; @@ -434,9 +418,9 @@ class XML_RPC_Server * that someone composed a single header with multiple lines, which * the RFCs allow. */ - $this->server_headers = $GLOBALS['XML_RPC_func_ereg_replace']("[\r\n]+[ \t]+", + $this->server_headers = preg_replace("@[\r\n]+[ \t]+@", ' ', trim($this->server_headers)); - $headers = $GLOBALS['XML_RPC_func_split']("[\r\n]+", $this->server_headers); + $headers = preg_split("@[\r\n]+@", $this->server_headers); foreach ($headers as $header) { header($header); @@ -685,4 +669,4 @@ class XML_RPC_Server * End: */ -?>
\ No newline at end of file +?> |