summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsmos <seth.mos@dds.nl>2012-03-30 10:08:28 +0200
committersmos <seth.mos@dds.nl>2012-03-30 10:08:28 +0200
commit31c43fd38bf9a2a1fce8a6219a33ab0c8f8a25c4 (patch)
treeb0da40dce488bde550b6f16fa1ffc992eed4a3ab
parent3f9cc8e44c5b50e588f0f916611ffa37f7ae0bcb (diff)
downloadpfsense-31c43fd38bf9a2a1fce8a6219a33ab0c8f8a25c4.zip
pfsense-31c43fd38bf9a2a1fce8a6219a33ab0c8f8a25c4.tar.gz
Add 6to4 support for automatic tunneling.
-rw-r--r--etc/inc/interfaces.inc97
-rwxr-xr-xusr/local/www/interfaces.php25
2 files changed, 117 insertions, 5 deletions
diff --git a/etc/inc/interfaces.inc b/etc/inc/interfaces.inc
index f04acbb..429290a 100644
--- a/etc/inc/interfaces.inc
+++ b/etc/inc/interfaces.inc
@@ -1129,6 +1129,13 @@ function interface_bring_down($interface = "wan", $destroy = false) {
pfSense_interface_flags($realif, -IFF_UP);
}
break;
+ case "6to4":
+ if(does_interface_exist("$realif")) {
+ mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
+ if ($destroy == true)
+ pfSense_interface_flags($realif, -IFF_UP);
+ }
+ break;
default:
if(does_interface_exist("$realif")) {
mwexec("/sbin/ifconfig " . escapeshellarg($realif) . " delete", true);
@@ -2871,6 +2878,9 @@ function interface_configure($interface = "wan", $reloadall = false, $linkupeven
case '6rd':
interface_6rd_configure($interface);
break;
+ case '6to4':
+ interface_6to4_configure($interface);
+ break;
default:
if (is_ipaddr($wancfg['ipaddrv6']) && $wancfg['subnetv6'] <> "") {
pfSense_interface_setaddress($realif, "{$wancfg['ipaddrv6']}/{$wancfg['subnetv6']}");
@@ -3054,6 +3064,93 @@ function interface_6rd_configure($interface = "wan"){
return 0;
}
+function interface_6to4_configure($interface = "wan"){
+ global $config, $g;
+ $iflist = get_configured_interface_with_descr(false, true);
+
+ /* because this is a tunnel interface we can only function
+ * with a public IPv4 address on the interface */
+
+ $wancfg = $config['interfaces'][$interface];
+ $wanif = $wancfg['if'];
+ if (empty($wancfg))
+ $wancfg = array();
+
+ $wanif = get_real_interface($interface);
+
+ $ip4address = find_interface_ip($wanif);
+ if((!is_ipaddrv4($ip4address)) || (is_private_ip($ip4address))) {
+ log_error("The interface IPv4 '{$ip4address}' address on interface '{$wanif}' is not public, not configuring 6RD tunnel");
+ return false;
+ }
+
+ /* create the long prefix notation for math, save the prefix length */
+ $stfprefixlen = 16;
+ $stfprefix = Net_IPv6::uncompress("2002::");
+ $stfarr = explode(":", $stfprefix);
+ $v4prefixlen = "0";
+
+ /* we need the hex form of the interface IPv4 address */
+ $ip4arr = explode(".", $ip4address);
+ $hexwanv4 = "";
+ foreach($ip4arr as $octet)
+ $hexwanv4 .= sprintf("%02x", $octet);
+
+ /* we need the hex form of the broker IPv4 address */
+ $ip4arr = explode(".", "192.88.99.1");
+ $hexbrv4 = "";
+ foreach($ip4arr as $octet)
+ $hexbrv4 .= sprintf("%02x", $octet);
+
+ /* binary presentation of the prefix for all 128 bits. */
+ $stfprefixbin = "";
+ foreach($stfarr as $element) {
+ $stfprefixbin .= sprintf("%016b", hexdec($element));
+ }
+ /* just save the left prefix length bits */
+ $stfprefixstartbin = substr($stfprefixbin, 0, $stfprefixlen);
+
+ /* if the prefix length is not 32 bits we need to shave bits off from the left of the v4 address. */
+ $stfbrokerbin = substr(sprintf("%032b", hexdec($hexbrv4)), $v4prefixlen, 32);
+ $stfbrokerbin = str_pad($stfprefixstartbin . $stfbrokerbin, 128, "0", STR_PAD_RIGHT);;
+
+ /* for the local subnet too. */
+ $stflanbin = substr(sprintf("%032b", hexdec($hexwanv4)), $v4prefixlen, 32);
+ $stflanbin = str_pad($stfprefixstartbin . $stflanbin, 128, "0", STR_PAD_RIGHT);;
+
+ /* convert the 128 bits for the broker address back into a valid IPv6 address */
+ $stfbrarr = array();
+ $stfbrbinarr = array();
+ $stfbrbinarr = str_split($stfbrokerbin, 16);
+ foreach($stfbrbinarr as $bin)
+ $stfbrarr[] = dechex(bindec($bin));
+ $stfbrarr[7] = 1;
+ $stfbrgw = Net_IPv6::compress(implode(":", $stfbrarr));
+
+ /* convert the 128 bits for the broker address back into a valid IPv6 address */
+ $stflanarr = array();
+ $stflanbinarr = array();
+ $stflanbinarr = str_split($stflanbin, 16);
+ foreach($stflanbinarr as $bin)
+ $stflanarr[] = dechex(bindec($bin));
+ $stflanpr = Net_IPv6::compress(implode(":", $stflanarr));
+ $stflanarr[7] = 1;
+ $stflan = Net_IPv6::compress(implode(":", $stflanarr));
+
+ /* setup the stf interface */
+ mwexec("/sbin/ifconfig stf0 destroy");
+ mwexec("/sbin/ifconfig stf0 create");
+ mwexec("/sbin/ifconfig stf0 inet6 {$stflanpr} prefixlen 16");
+
+ log_error("Set IPv6 address inet6 {$stflanpr} prefixlen 16 for stf0, route {$stfbrgw}");
+
+ /* write out a default router file */
+ file_put_contents("{$g['tmp_path']}/{$wanif}_routerv6", "{$stfbrgw}");
+ file_put_contents("{$g['tmp_path']}/{$wanif}_defaultgwv6", "{$stfbrgw}");
+
+ return 0;
+}
+
function interface_dhcpv6_configure($interface = "wan") {
global $config, $g;
$iflist = get_configured_interface_with_descr(false, true);
diff --git a/usr/local/www/interfaces.php b/usr/local/www/interfaces.php
index 6d5a562..b0594df 100755
--- a/usr/local/www/interfaces.php
+++ b/usr/local/www/interfaces.php
@@ -220,6 +220,9 @@ switch($wancfg['ipaddrv6']) {
$pconfig['dhcp6-ia-pd-len'] = $wancfg['dhcp6-ia-pd-len'];
$pconfig['type6'] = "dhcp6";
break;
+ case "6to4":
+ $pconfig['type6'] = "6to4";
+ break;
case "6rd":
$pconfig['prefix-6rd'] = $wancfg['prefix-6rd'];
if($wancfg['prefix-6rd-v4plen'] == "")
@@ -500,6 +503,10 @@ if ($_POST['apply']) {
if (in_array($wancfg['ipaddrv6'], array()))
$input_errors[] = sprintf(gettext("You have to reassign the interface to be able to configure as %s."),$_POST['type']);
break;
+ case "6to4":
+ if (in_array($wancfg['ipaddrv6'], array()))
+ $input_errors[] = sprintf(gettext("You have to reassign the interface to be able to configure as %s."),$_POST['type']);
+ break;
}
@@ -669,6 +676,7 @@ if ($_POST['apply']) {
/* for dynamic interfaces we tack a gateway item onto the array to prevent system
* log messages from appearing. They can also manually add these items */
/* 1st added gateway gets a default bit */
+ /* FIXME: Add address family check here! */
if(!empty($a_gateways)) {
$gateway_item = array();
/* check for duplicates */
@@ -816,6 +824,9 @@ if ($_POST['apply']) {
$a_gateways[] = $gateway_item;
}
break;
+ case "6to4":
+ $wancfg['ipaddrv6'] = "6to4";
+ break;
case "none":
break;
}
@@ -1068,7 +1079,7 @@ $statusurl = "status_interfaces.php";
$closehead = false;
include("head.inc");
$types4 = array("none" => gettext("None"), "staticv4" => gettext("Static IPv4"), "dhcp" => gettext("DHCP"), "ppp" => gettext("PPP"), "pppoe" => gettext("PPPoE"), "pptp" => gettext("PPTP"), "l2tp" => gettext("L2TP") /* , "carpdev-dhcp" => "CarpDev"*/);
-$types6 = array("none" => gettext("None"), "staticv6" => gettext("Static IPv6"), "dhcp6" => gettext("DHCP6"), "6rd" => gettext("6RD"));
+$types6 = array("none" => gettext("None"), "staticv6" => gettext("Static IPv6"), "dhcp6" => gettext("DHCP6"), "6rd" => gettext("6rd"), "6to4" => gettext("6to4"));
?>
@@ -1115,19 +1126,23 @@ $types6 = array("none" => gettext("None"), "staticv6" => gettext("Static IPv6"),
function updateTypeSix(t) {
switch(t) {
case "none": {
- jQuery('#staticv6, #dhcp6, #6rd').hide();
+ jQuery('#staticv6, #dhcp6, #6rd, #6to4').hide();
break;
}
case "staticv6": {
- jQuery('#none, #dhcp6, #6rd').hide();
+ jQuery('#none, #dhcp6, #6rd, #6to4').hide();
break;
}
case "dhcp6": {
- jQuery('#none, #staticv6, #6rd').hide();
+ jQuery('#none, #staticv6, #6rd, #6to4').hide();
break;
}
case "6rd": {
- jQuery('#none, #dhcp6, #staticv6').hide();
+ jQuery('#none, #dhcp6, #staticv6, #6to4').hide();
+ break;
+ }
+ case "6to4": {
+ jQuery('#none, #dhcp6, #staticv6, #6rd').hide();
break;
}
}
OpenPOWER on IntegriCloud