diff options
Diffstat (limited to 'etc')
-rw-r--r-- | etc/bogonsv6 | 0 | ||||
-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 | 317 | ||||
-rw-r--r-- | etc/inc/filter_log.inc | 4 | ||||
-rw-r--r-- | etc/inc/gwlb.inc | 79 | ||||
-rw-r--r-- | etc/inc/interfaces.inc | 227 | ||||
-rw-r--r-- | etc/inc/pfsense-utils.inc | 29 | ||||
-rw-r--r-- | etc/inc/rrd.inc | 39 | ||||
-rw-r--r-- | etc/inc/services.inc | 358 | ||||
-rw-r--r-- | etc/inc/system.inc | 110 | ||||
-rw-r--r-- | etc/inc/upgrade_config.inc | 80 | ||||
-rw-r--r-- | etc/inc/util.inc | 80 | ||||
-rw-r--r-- | etc/inc/vslb.inc | 4 | ||||
-rw-r--r-- | etc/inc/xmlrpc_client.inc | 141 | ||||
-rw-r--r-- | etc/inc/xmlrpc_server.inc | 36 | ||||
-rwxr-xr-x | etc/rc.banner | 10 | ||||
-rwxr-xr-x | etc/rc.filter_synchronize | 2 | ||||
-rwxr-xr-x | etc/rc.update_bogons.sh | 23 |
21 files changed, 1287 insertions, 287 deletions
diff --git a/etc/bogonsv6 b/etc/bogonsv6 new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/etc/bogonsv6 diff --git a/etc/inc/authgui.inc b/etc/inc/authgui.inc index 9655d79..650c7b9 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" @@ -261,4 +267,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 b5b1620..45d3f74 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") @@ -229,7 +229,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 */ @@ -244,6 +244,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") @@ -271,7 +272,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); @@ -290,7 +292,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; @@ -319,7 +321,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."; @@ -330,4 +332,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 18428fc..3f9fe33 100644 --- a/etc/inc/filter.inc +++ b/etc/inc/filter.inc @@ -733,17 +733,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; @@ -1234,6 +1238,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'])) { @@ -1360,8 +1393,6 @@ function filter_nat_rules_generate() { } if($numberofnathosts > 0): foreach ($FilterIflist as $if => $ifcfg) { - if (substr($ifcfg['if'], 0, 4) == "ovpn") - continue; update_filter_reload_status("Creating outbound rules {$if} - ({$ifcfg['descr']})"); if(interface_has_gateway($if)) { $target = $ifcfg['ip']; @@ -1576,51 +1607,89 @@ 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']['ip'], $FilterIflist['pptp']['sn']); - $pptpsn = $FilterIflist['pptp']['sn']; - $src = "{$pptpsa}/{$pptpsn}"; - break; - case 'pppoe': - $pppoesa = gen_subnet($FilterIflist['pppoe']['ip'], $FilterIflist['pppoe']['sn']); - $pppoesn = $FilterIflist['pppoe']['sn']; - $src = "{$pppoesa}/{$pppoesn}"; - break; + 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; + } + 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']['ip'], $FilterIflist['pptp']['sn']); + $pptpsn = $FilterIflist['pptp']['sn']; + $src = "{$pptpsa}/{$pptpsn}"; + break; + case 'pppoe': + $pppoesa = gen_subnet($FilterIflist['pppoe']['ip'], $FilterIflist['pppoe']['sn']); + $pppoesn = $FilterIflist['pppoe']['sn']; + $src = "{$pppoesa}/{$pppoesn}"; + break; + } + if(isset($rule[$target]['not'])) $src = "!{$src}"; } - if(isset($rule[$target]['not'])) - $src = "!{$src}"; } } else if($rule[$target]['address']) { $expsrc = alias_expand($rule[$target]['address']); @@ -1706,6 +1775,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']}"); @@ -1742,12 +1822,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 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_ipaddr($rg)) { + $aline['reply'] = "reply-to ( {$ifcfg['if']} {$rg} ) "; + } else { + if($rule['interface'] <> "pptp") { + log_error("Could not find gateway for interface({$rule['interface']})."); + } } } } @@ -1763,8 +1854,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 { @@ -1802,6 +1895,8 @@ function filter_generate_user_rule($rule) { } if(($rule['protocol'] == "icmp") && $rule['icmptype']) $aline['icmp-type'] = "icmp-type {$rule['icmptype']} "; + if(($rule['protocol'] == "icmp6") && $rule['icmptype']) + $aline['icmp6-type'] = "icmp-type {$rule['icmptype']} "; if(!empty($rule['tag'])) $aline['tag'] = " tag " .$rule['tag']. " "; if(!empty($rule['tagged'])) @@ -1957,8 +2052,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"; @@ -1966,8 +2061,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']; @@ -2001,20 +2096,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 @@ -2106,10 +2224,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++; @@ -2131,10 +2252,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; } @@ -2166,6 +2288,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" @@ -2182,6 +2305,18 @@ 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 {$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; } } @@ -2193,24 +2328,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']['mobileclients']['enable'])) @@ -2327,19 +2470,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/gwlb.inc b/etc/inc/gwlb.inc index a192bd3..cc9aa74 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 @@ -501,35 +506,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['gateway']) && 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); } -?>
\ No newline at end of file +?> diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc index be118a8..07a5320 100644 --- a/etc/inc/interfaces.inc +++ b/etc/inc/interfaces.inc @@ -735,7 +735,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; } @@ -778,7 +781,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']) @@ -788,9 +795,13 @@ function interface_gif_configure(&$gif, $gifkey = "") { else log_error("could not bring gifif up -- variable not defined"); - /* XXX: Needed?! */ + /* XXX: Needed?! Let them use the defined gateways instead */ //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']); + + 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; } @@ -1299,6 +1310,7 @@ startup: default: {$ppp['type']}client: create bundle static {$interface} + set bundle enable ipv6cp set iface name {$pppif} EOD; @@ -1811,12 +1823,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 */ @@ -1831,11 +1854,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); @@ -2479,6 +2509,7 @@ function find_dhclient_process($interface) { 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]; @@ -2490,6 +2521,7 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven if (!$g['booting']) { /* remove all IPv4 addresses */ while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " -alias", true) == 0); + while (mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " inet6 -alias", true) == 0); switch ($wancfg['ipaddr']) { case 'pppoe': @@ -2604,6 +2636,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': @@ -2639,6 +2673,18 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven break; } + switch ($wancfg['ipaddrv6']) { + case 'dhcpv6': + interface_dhcpv6_configure($interface); + break; + default: + if ($wancfg['ipaddrv6'] <> "" && $wancfg['subnetv6'] <> "") { + pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}"); + mwexec("/sbin/ifconfig {$realif} inet6 {$wancfg['ipaddrv6']} prefixlen {$wancfg['subnetv6']} "); + } + break; + } + if(does_interface_exist($wancfg['if'])) interfaces_bring_up($wancfg['if']); @@ -3094,13 +3140,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]; + } } } } @@ -3149,8 +3210,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; } @@ -3334,6 +3409,45 @@ 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); + 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; @@ -3352,6 +3466,39 @@ 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); + 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; @@ -3392,6 +3539,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); @@ -3411,6 +3577,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/pfsense-utils.inc b/etc/inc/pfsense-utils.inc index 08ec7d5..2764135 100644 --- a/etc/inc/pfsense-utils.inc +++ b/etc/inc/pfsense-utils.inc @@ -1024,15 +1024,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; + } } } @@ -1110,6 +1121,8 @@ 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); @@ -1262,8 +1275,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 = ""; @@ -2158,4 +2173,4 @@ function filter_rules_compare($a, $b) { return compare_interface_friendly_names($a['interface'], $b['interface']); } -?>
\ No newline at end of file +?> diff --git a/etc/inc/rrd.inc b/etc/inc/rrd.inc index 52b826b..c5171fe 100644 --- a/etc/inc/rrd.inc +++ b/etc/inc/rrd.inc @@ -252,6 +252,7 @@ function enable_rrd_graphing() { /* db update script */ $rrdupdatesh = "#!/bin/sh\n"; $rrdupdatesh .= "\n"; + $rrdupdatesh .= "export TERM=serial\n"; $rrdupdatesh .= "counter=1\n"; $rrdupdatesh .= "while [ \"\$counter\" -ne 0 ]\n"; $rrdupdatesh .= "do\n"; @@ -283,6 +284,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 "; @@ -293,17 +298,13 @@ 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:\\\n"; + $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass|In6\/Pass|Out6\/Pass|In4\/Block|Out4\/Block|In6\/Block|Out6\/Block/ {printf \$6 \":\"}'|sed -e 's/.\$//'`\n"; /* PACKETS, set up the rrd file */ if (!file_exists("$rrddbpath$ifname$packets")) { @@ -312,6 +313,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 "; @@ -322,16 +327,21 @@ 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"; +<<<<<<< HEAD + $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$packets N:\\\n"; + $rrdupdatesh .= "`$pfctl -vvsI -i {$realif} | awk '/In4\/Pass|Out4\/Pass|In6\/Pass|Out6\/Pass|In4\/Block|Out4\/Block|In6\/Block|Out6\/Block/ {printf \$4 \":\"}'|sed -e 's/.\$//'`\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"; +>>>>>>> upstream/master /* WIRELESS, set up the rrd file */ if($config['interfaces'][$ifname]['wireless']['mode'] == "bss") { @@ -566,11 +576,12 @@ function enable_rrd_graphing() { } /* the CPU stats gathering function. */ - $rrdupdatesh .= "`$top -d 2 -s 1 0 | $awk '{gsub(/%/, \"\")} BEGIN { \\\n"; - $rrdupdatesh .= "printf \"$rrdtool update $rrddbpath$ifname$proc \" } \\\n"; + $rrdupdatesh .= "$top -d 2 -s 1 0 | tail -n7 > /tmp/top_output.txt\n"; + $rrdupdatesh .= "$rrdtool update $rrddbpath$ifname$proc N:\\\n"; + $rrdupdatesh .= "`$awk < /tmp/top_output.txt '{gsub(/%/, \"\")} \\\n"; $rrdupdatesh .= "{ if ( \$2 == \"processes:\" ) { processes = \$1; } \\\n"; $rrdupdatesh .= "else if ( \$1 == \"CPU:\" ) { user = \$2; nice = \$4; sys = \$6; interrupt = \$8; } \\\n"; - $rrdupdatesh .= "} END { printf \"N:\"user\":\"nice\":\"sys\":\"interrupt\":\"processes }'`\n\n"; + $rrdupdatesh .= "} END { printf user\":\"nice\":\"sys\":\"interrupt\":\"processes }'`\n\n"; /* End CPU statistics */ @@ -774,7 +785,9 @@ function enable_rrd_graphing() { } function kill_traffic_collector() { + mwexec("killall top", true); + mwexec("killall rrdtool", true); mwexec("/bin/pkill -f updaterrd.sh", true); } -?>
\ No newline at end of file +?> diff --git a/etc/inc/services.inc b/etc/inc/services.inc index 1a03021..3e22efb 100644 --- a/etc/inc/services.inc +++ b/etc/inc/services.inc @@ -35,10 +35,81 @@ 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 */ +/* implement ipv6 route advertising deamon */ +function services_rtadvd_configure() { + global $config, $g; + + if(isset($config['system']['developerspew'])) { + $mt = microtime(); + echo "services_rtadvd_configure() being called $mt\n"; + } + + if($g['services_dhcp_server_enable'] == false) + return; + + if(is_process_running("rtadvd")) { + mwexec("killall -9 rtadvd", true); + } + + /* DHCP enabled on any interfaces? */ + if (!is_dhcp_server_enabled()) + return 0; + + 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, managed=64, stateful=128, both=192 */ + + $rtadvdconf = "# Automatically Generated, do not edit\n"; + $rtadvdnum = 0; + foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + $rtadvdnum++; + /* It appears we can not advertise the gateway IP (carp) + * rtadvd[44205]: <sock_open> IPV6_JOIN_GROUP(link) on vip1: Can't assign requested address + if($dhcpv6ifconf['gateway'] <> "") { + $dhcpv6if = find_carp_interface($dhcpv6ifconf['gateway']); + } + */ + $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 .= "{$realif}:\\\n"; + $rtadvdconf .= "\t:addr=\"{$subnetv6}\":\\\n"; + $rtadvdconf .= "\t:prefixlen#{$ifcfgsnv6}:\\\n"; + $rtadvdconf .= "\t:raflags#192:\n"; + $rtadvdconf .= "\n"; + + } + + 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; @@ -51,8 +122,9 @@ function services_dhcpd_configure() { } /* kill any running dhcpd */ - if(is_process_running("dhcpd")) + if(is_process_running("dhcpd")) { mwexec("killall dhcpd", true); + } /* DHCP enabled on any interfaces? */ if (!is_dhcp_server_enabled()) @@ -97,11 +169,25 @@ function services_dhcpd_configure() { log_error("DHCP leases restore failed exited with $dhcpreturn, the error is: $dhcprestore\n"); } } + 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['dhcpd'])) + $config['dhcpd'] = array(); + if (!is_array($config['dhcpdv6'])) + $config['dhcpdv6'] = array(); $dhcpdcfg = $config['dhcpd']; + $dhcpdv6cfg = $config['dhcpdv6']; $Iflist = get_configured_interface_list(); if ($g['booting']) @@ -111,8 +197,9 @@ 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"); + $fdv6 = fopen("{$g['dhcpd_chroot_path']}/etc/dhcpdv6.conf", "w"); + if ((!$fd) || (! $fdv6)) { + printf("Error: cannot open dhcpd.conf or dhcpdv6.conf in services_dhcpd_configure().\n"); return 1; } @@ -128,6 +215,14 @@ function services_dhcpd_configure() { } } } + $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"; + } + } + } $dhcpdconf = <<<EOD @@ -145,13 +240,34 @@ ping-check true; EOD; + $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($dhcpifconf['disableauthoritative'])) $dhcpdconf .= "authoritative;\n"; + if(!isset($dhcpv6ifconf['disableauthoritative'])) + $dhcpdv6conf .= "authoritative;\n"; if(isset($dhcpifconf['alwaysbroadcast'])) $dhcpdconf .= "always-broadcast on\n"; + if(isset($dhcpv6ifconf['alwaysbroadcast'])) + $dhcpdv6conf .= "always-broadcast on\n"; $dhcpdifs = array(); + $dhcpdv6ifs = array(); /* loop through and determine if we need to setup * failover peer "bleh" entries @@ -214,6 +330,64 @@ EOPP; $dhcpnum++; } } + $dhcpv6num = 0; + foreach ($dhcpdv6cfg as $dhcpv6if => $dhcpv6ifconf) { + + interfaces_staticarp_configure($dhcpv6if); + + 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++; + } + } $dhcpnum = 0; @@ -294,8 +468,7 @@ EOPP; $dnscfg EOD; - - // default-lease-time + // default-lease-time if ($dhcpifconf['defaultleasetime']) $dhcpdconf .= " default-lease-time {$dhcpifconf['defaultleasetime']};\n"; @@ -377,17 +550,185 @@ EOD; $dhcpdifs[] = get_real_interface($dhcpif); } + $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_mask($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])) { + $dnscfgv6 .= " option dhcp6.name-servers " . join(",", $syscfg['dnsserver']) . ";"; + } + + $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; + // 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 */ + if (is_array($dhcpv6ifconf['staticmap'])) { + + $i = 0; + foreach ($dhcpv6ifconf['staticmap'] as $sm) { + $dhcpdv6conf .= <<<EOD +host s_{$dhcpv6if}_{$i} { + hardware ethernet {$sm['mac']}; + +EOD; + if ($sm['ipaddr']) + $dhcpdv6conf .= " fixed-address6 {$sm['ipaddr']};\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++; + } + } + + + $realif = escapeshellcmd(get_real_interface($dhcpv6if)); + $dhcpdv6ifs[] = $realif; + /* Create link local address for bridges */ + if(stristr("$realif", "bridge")) { + mwexec("$ifconfig {$realif} inet6 fe80::/64 eui64"); + } + } + fwrite($fd, $dhcpdconf); fclose($fd); + fwrite($fdv6, $dhcpdv6conf); + fclose($fdv6); /* create an empty leases database */ touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd.leases"); touch("{$g['varrun_path']}/dhcpd.pid"); + /* create an empty leases v6 database */ + touch("{$g['dhcpd_chroot_path']}/var/db/dhcpd6.leases"); + touch("{$g['varrun_path']}/dhcpdv6.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 " . + join(" ", $dhcpdifs)); + } + + if(count($dhcpdv6ifs) > 0) { + mwexec("/usr/local/sbin/dhcpd -6 -user dhcpd -group _dhcp -chroot {$g['dhcpd_chroot_path']} -cf /etc/dhcpdv6.conf " . + join(" ", $dhcpdv6ifs)); + mwexec("/usr/sbin/rtadvd " . join(" ", $dhcpdv6ifs)); + } + + /* start ipv6 route advertising if required */ + services_rtadvd_configure(); if ($g['booting']) { print "done.\n"; @@ -614,6 +955,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 4a8214d..535b4d8 100644 --- a/etc/inc/system.inc +++ b/etc/inc/system.inc @@ -317,14 +317,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") @@ -340,6 +346,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"); @@ -347,6 +368,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']) { @@ -357,7 +384,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); @@ -372,7 +399,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"; @@ -382,6 +409,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(); @@ -394,17 +446,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)); } } @@ -420,7 +478,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() { @@ -902,6 +962,7 @@ EOD; ## FreeBSD! server.event-handler = "freebsd-kqueue" server.network-backend = "writev" +#server.use-ipv6 = "enable" ## modules to load server.modules = ( @@ -1015,7 +1076,42 @@ 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:443\" { }\n"; + $lighty_config .= "\$SERVER[\"socket\"] == \"[::1]:443\" { \n"; + $lighty_config .= "\$SERVER[\"socket\"] == \"[::1]:443\" { \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:443\" { }\n"; + $lighty_config .= "\$SERVER[\"socket\"] == \"[::]:443\" { \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 f09b9bb..fee3786 100644 --- a/etc/inc/upgrade_config.inc +++ b/etc/inc/upgrade_config.inc @@ -1758,7 +1758,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}"); @@ -2308,6 +2308,84 @@ function upgrade_075_to_076() { function upgrade_076_to_077() { 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']); diff --git a/etc/inc/util.inc b/etc/inc/util.inc index b7df86b..cf531ce 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; @@ -952,6 +1021,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)); diff --git a/etc/inc/vslb.inc b/etc/inc/vslb.inc index 2c3f0ca..55bcfdf 100644 --- a/etc/inc/vslb.inc +++ b/etc/inc/vslb.inc @@ -280,7 +280,7 @@ function relayd_configure() { mwexec('pkill relayd'); } } else { - if (! empty($vs_a)) { + if (count($vs_a) > 0) { // not running and there is a config, start it mwexec("/usr/local/sbin/relayd -f {$g['varetc_path']}/relayd.conf"); } @@ -354,4 +354,4 @@ function get_lb_summary() { return $relay_hosts; } -?>
\ No newline at end of file +?> diff --git a/etc/inc/xmlrpc_client.inc b/etc/inc/xmlrpc_client.inc index a3b9cad..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. @@ -2077,4 +2050,4 @@ function XML_RPC_encode($php_val) * End: */ -?>
\ No newline at end of file +?> 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 +?> diff --git a/etc/rc.banner b/etc/rc.banner index 6f81cb9..2e016ce 100755 --- a/etc/rc.banner +++ b/etc/rc.banner @@ -70,15 +70,21 @@ break; } $ipaddr = get_interface_ip($ifname); + $subnet = get_interface_subnet($ifname); + $ipaddr6 = get_interface_ipv6($ifname); + $subnet6 = get_interface_subnetv6($ifname); $realif = get_real_interface($ifname); $tobanner = "{$friendly} ({$ifname})"; - printf("\n %-25s -> %-10s -> %s %s", + printf("\n %-15s -> %-10s -> %s/%s\t%s/%s %s", $tobanner, $realif, $ipaddr ? $ipaddr : "NONE", + $subnet ? $subnet : "NONE", + $ipaddr6 ? $ipaddr6 : "NONE", + $subnet6 ? $subnet6 : "NONE", $class ); } -?>
\ No newline at end of file +?> diff --git a/etc/rc.filter_synchronize b/etc/rc.filter_synchronize index ed80306..28b08cf 100755 --- a/etc/rc.filter_synchronize +++ b/etc/rc.filter_synchronize @@ -291,6 +291,8 @@ if (is_array($config['installedpackages']['carpsettings']['config'])) { $port = "443"; } + if(is_ipaddrv6($carp['synchronizetoip'])) + $carp['synchronizetoip'] = "[{$carp['synchronizetoip']}]"; $synchronizetoip .= $carp['synchronizetoip']; if ($carp['synchronizerules'] != "") { if (!is_array($config['filter'])) diff --git a/etc/rc.update_bogons.sh b/etc/rc.update_bogons.sh index 52cfc1a..52ec92f 100755 --- a/etc/rc.update_bogons.sh +++ b/etc/rc.update_bogons.sh @@ -28,6 +28,15 @@ if [ ! -f /tmp/bogons ]; then exit fi +/usr/bin/fetch -q -o /tmp/bogonsv6 "http://files.pfsense.org/mirrors/fullbogons-ipv6.txt" +if [ ! -f /tmp/bogonsv6 ]; then + echo "Could not download http://files.pfsense.org/mirrors/fullbogons-ipv6.txt" | logger + # Relaunch and sleep + sh /etc/rc.update_bogons.sh & + exit +fi + + BOGON_MD5=`/usr/bin/fetch -q -o - "http://files.pfsense.org/mirrors/bogon-bn-nonagg.txt.md5" | awk '{ print $4 }'` ON_DISK_MD5=`md5 /tmp/bogons | awk '{ print $4 }'` if [ "$BOGON_MD5" = "$ON_DISK_MD5" ]; then @@ -42,5 +51,19 @@ else sh /etc/rc.update_bogons.sh & fi +BOGON_MD5=`/usr/bin/fetch -q -o - "http://files.pfsense.org/mirrors/fullbogons-ipv6.txt.md5" | awk '{ print $4 }'` +ON_DISK_MD5=`md5 /tmp/bogonsv6 | awk '{ print $4 }'` +if [ "$BOGON_MD5" = "$ON_DISK_MD5" ]; then + egrep -v "^#" /tmp/bogonsv6 > /etc/bogonsv6 + /etc/rc.conf_mount_ro + RESULT=`/sbin/pfctl -t bogonsv6 -T replace -f /etc/bogonsv6 2>&1` + rm /tmp/bogons + echo "Bogons files downloaded: $RESULT" | logger +else + echo "Could not download http://files.pfsense.org/mirrors/fullbogons-ipv6.txt.md5 (md5 mismatch)" | logger + # Relaunch and sleep + sh /etc/rc.update_bogons.sh & +fi + echo "rc.update_bogons.sh is ending the update cycle." | logger |