diff options
author | Ermal <eri@pfsense.org> | 2010-04-20 18:32:59 +0000 |
---|---|---|
committer | Ermal <eri@pfsense.org> | 2010-04-20 18:32:59 +0000 |
commit | 1dbe445acc2b74c4a610e397c0c15031d99666e5 (patch) | |
tree | dc3b2f6fd668a6180fb8a009c9200e92cf6423c2 | |
parent | 0d388969180882e133f0ec062b8da7cb9d969896 (diff) | |
download | pfsense-1dbe445acc2b74c4a610e397c0c15031d99666e5.zip pfsense-1dbe445acc2b74c4a610e397c0c15031d99666e5.tar.gz |
Use tables of ipfw for passthrough mac entries. This makes it scale way better than previously. Fix multiple entries on adding mac through entries automatically after login for the same user. The changes allow even pass through mac to be controlled from the Status->Captiveportal. Use serialize/unserialize on some files that keep temporary information to speed up calculations. Really allow mac passthrough to follow radius rules or time out rules when present.
-rw-r--r-- | etc/inc/captiveportal.inc | 81 | ||||
-rwxr-xr-x | usr/local/captiveportal/index.php | 49 | ||||
-rwxr-xr-x | usr/local/www/services_captiveportal_ip_edit.php | 16 | ||||
-rwxr-xr-x | usr/local/www/services_captiveportal_mac.php | 6 | ||||
-rwxr-xr-x | usr/local/www/services_captiveportal_mac_edit.php | 2 |
5 files changed, 55 insertions, 99 deletions
diff --git a/etc/inc/captiveportal.inc b/etc/inc/captiveportal.inc index c7095d6..b5bc8ac 100644 --- a/etc/inc/captiveportal.inc +++ b/etc/inc/captiveportal.inc @@ -126,8 +126,7 @@ function captiveportal_configure() { $cprules = captiveportal_rules_generate($cpinterface, $cpips); $cprules .= "\n"; /* generate passthru mac database */ - $cprules .= captiveportal_passthrumac_configure(true); - $cprules .= "\n"; + captiveportal_passthrumac_configure(true); /* allowed ipfw rules to make allowed ip work */ $cprules .= captiveportal_allowedip_configure(); @@ -485,10 +484,6 @@ function captiveportal_prune_old() { $timedout = false; $term_cause = 1; - /* no pruning for fixed mac address entry */ - if (portal_mac_fixed($cpdb[$i][3])) { - continue; // check next value - } /* hard timeout? */ if ($timeout) { if ((time() - $cpdb[$i][0]) >= $timeout) { @@ -627,6 +622,7 @@ function captiveportal_disconnect($dbent, $radiusservers,$term_cause = 1,$stop_t /* Delete client's ip entry from tables 3 and 4. */ mwexec("/sbin/ipfw table 1 delete {$dbent[2]}"); mwexec("/sbin/ipfw table 2 delete {$dbent[2]}"); + /* Release the ruleno so it can be reallocated to new clients. */ captiveportal_free_ipfw_ruleno($dbent[1]); @@ -712,64 +708,22 @@ function captiveportal_passthrumac_configure($lock = false) { /* clear out passthru macs, if necessary */ unlink_if_exists("{$g['vardb_path']}/captiveportal_mac.db"); - $rules = ""; if (is_array($config['captiveportal']['passthrumac'])) { - - $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db", "w"); - if (!$fd) { - printf("Error: cannot open passthru mac DB file in captiveportal_passthrumac_configure().\n"); - unlock($captiveportallck); - return 1; - } - - $peruserbw = isset($config['captiveportal']['peruserbw']); - $macdb = ""; + $macdb = array(); foreach ($config['captiveportal']['passthrumac'] as $macent) { - $ruleno = captiveportal_get_next_ipfw_ruleno(); - - $macdb .= $macent['mac'] . "\n"; - - /* pfSense: - * pass through mac entries should always exist. the reason - * for this is because we do not have native mac address filtering - * mechanisms. this allows us to filter by mac address easily - * and get around this limitation. I consider this a bug in - * m0n0wall and pfSense as m0n0wall does not have native mac - * filtering mechanisms as well. -Scott Ullrich - * - * Add rules for traffic shaping. - * This assumes that net.inet.ip.fw.one_pass: 1 is set. - */ - - $actionup = "allow"; - $actiondown = "allow"; - if ($peruserbw) { - $bw_up = isset($macent['bw_up']) ? trim($macent['bw_up']) : $config['captiveportal']['bwdefaultup']; - $bw_down = isset($macent['bw_down']) ? trim($macent['bw_down']) : $config['captiveportal']['bwdefaultdn']; - if (!empty($bw_up) && is_numeric($bw_up)) { - $bw_up_pipeno = $ruleno + 20000; - $rules .= "pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100\n"; - $actionup = "pipe {$bw_up_pipeno}"; - } - if (!empty($bw_down) && is_numeric($bw_down)) { - $bw_down_pipeno = $ruleno + 20001; - $rules .= "pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100\n"; - $actiondown = "pipe {$bw_down_pipeno}"; - } - } - $rules .= "add {$ruleno} {$actionup} ip from any to any MAC {$macent['mac']} any\n"; - $ruleno++; - $rules .= "add {$ruleno} {$actiondown} ip from any to any MAC any {$macent['mac']}\n"; + $macdb[$macent['mac']]['active'] = true; + if (isset($macent['bw_up'])) + $macdb[$macent['mac']]['bw_up'] = $macent['bw_up']; + if (isset($macent['bw_down'])) + $macdb[$macent['mac']]['bw_down'] = $macent['bw_down']; + } /* record passthru MACs so can be recognized and let thru */ - fwrite($fd, $macdb); - fclose($fd); + file_put_contents("{$g['vardb_path']}/captiveportal_mac.db", serialize($macdb)); } if (!$lock) unlock($captiveportallck); - - return $rules; } function captiveportal_allowedip_configure() { @@ -1139,18 +1093,9 @@ function portal_mac_fixed($clientmac) { /* open captive portal mac db */ if (file_exists("{$g['vardb_path']}/captiveportal_mac.db")) { - $fd = @fopen("{$g['vardb_path']}/captiveportal_mac.db","r") ; - if (!$fd) { - return FALSE; - } - while (!feof($fd)) { - $mac = trim(fgets($fd)) ; - if(strcasecmp($clientmac, $mac) == 0) { - fclose($fd) ; - return TRUE ; - } - } - fclose($fd) ; + $macdb = unserialize(file_get_contents("{$g['vardb_path']}/captiveportal_mac.db")); + if (isset($macdb[$clientmac])) + return $macdb[$clientmac]; } return FALSE ; } diff --git a/usr/local/captiveportal/index.php b/usr/local/captiveportal/index.php index c2f886c..17e3c2f 100755 --- a/usr/local/captiveportal/index.php +++ b/usr/local/captiveportal/index.php @@ -117,13 +117,11 @@ setTimeout('window.close();',5000) ; </HTML> EOD; -/* NOTE: This is not needed now that CP works only at layer2. - * The $macfilter can be removed safely since we first check if the $clientmac is present, if not we fail +/* The $macfilter can be removed safely since we first check if the $clientmac is present, if not we fail */ } else if ($clientmac && portal_mac_fixed($clientmac)) { - // punch hole in ipfw for pass thru mac addresses + /* punch hole in ipfw for pass thru mac addresses */ portal_allow($clientip, $clientmac, "unauthenticated"); exit; -*/ } else if ($clientmac && $radmac_enable && portal_mac_radius($clientmac,$clientip)) { /* radius functions handle everything so we exit here since we're done */ @@ -322,13 +320,22 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut */ $peruserbw = isset($config['captiveportal']['peruserbw']); $passthrumacadd = isset($config['captiveportal']['passthrumacadd']); - - $bw_up = isset($attributes['bw_up']) ? trim($attributes['bw_up']) : $config['captiveportal']['bwdefaultup']; - $bw_down = isset($attributes['bw_down']) ? trim($attributes['bw_down']) : $config['captiveportal']['bwdefaultdn']; + $portalmac = NULL; + if (!empty($clientmac)) { + $portalmac = portal_mac_fixed($clientmac); + if ($portalmac) { + $attributes['bw_up'] = $portalmac['bw_up']; + $attributes['bw_down'] = $portalmac['bw_down']; + } + } - if ($passthrumacadd) { + $bw_up = isset($attributes['bw_up']) ? trim($attributes['bw_up']) : $config['captiveportal']['bwdefaultup']; + $bw_down = isset($attributes['bw_down']) ? trim($attributes['bw_down']) : $config['captiveportal']['bwdefaultdn']; + + if ($passthrumacadd && $portalmac == NULL) { $mac = array(); $mac['mac'] = $clientmac; + $mac['descr'] = "Auto added mac passthrough with user {$username}"; if (!empty($bw_up)) $mac['bw_up'] = $bw_up; if (!empty($bw_down)) @@ -343,18 +350,13 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut $bw_up_pipeno = $ruleno + 20000; //$bw_up /= 1000; // Scale to Kbit/s mwexec("/sbin/ipfw pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100"); - mwexec("echo 'pipe {$bw_up_pipeno} config bw {$bw_up}Kbit/s queue 100' > /tmp/testing"); - if ($passthrumacadd) { - mwexec("/sbin/ipfw add {$ruleno} pipe {$bw_up_pipeno} ip from any to any MAC {$clientmac} any"); - } else if (!isset($config['captiveportal']['nomacfilter'])) + if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac} {$bw_up_pipeno}"); else mwexec("/sbin/ipfw table 1 add {$clientip} {$bw_up_pipeno}"); } else { - if ($passthrumacadd) { - mwexec("/sbin/ipfw add {$ruleno} allow ip from any to any MAC {$clientmac} any"); - } else if (!isset($config['captiveportal']['nomacfilter'])) + if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) mwexec("/sbin/ipfw table 1 add {$clientip} mac {$clientmac}"); else mwexec("/sbin/ipfw table 1 add {$clientip}"); @@ -362,21 +364,14 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut if ($peruserbw && !empty($bw_down) && is_numeric($bw_down)) { $bw_down_pipeno = $ruleno + 20001; //$bw_down /= 1000; // Scale to Kbit/s - mwexec("/sbin/ipfw pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100"); - mwexec("echo 'pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100' > /tmp/testing"); + mwexec("/sbin/ipfw pipe {$bw_down_pipeno} config bw {$bw_down}Kbit/s queue 100"); - if ($passthrumacadd) { - $ruledown = $ruleno + 1; - mwexec("/sbin/ipfw add {$ruledown} pipe {$bw_down_pipeno} ip from any to any MAC any {$clientmac}"); - } else if (!isset($config['captiveportal']['nomacfilter'])) + if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac} {$bw_down_pipeno}"); else mwexec("/sbin/ipfw table 2 add {$clientip} {$bw_down_pipeno}"); } else { - if ($passthrumacadd) { - $ruledown = $ruleno + 1; - mwexec("/sbin/ipfw add {$ruleno} allow ip from any to any MAC {$clientmac} any"); - } else if (!isset($config['captiveportal']['nomacfilter'])) + if (!isset($config['captiveportal']['nomacfilter']) || $passthrumacadd) mwexec("/sbin/ipfw table 2 add {$clientip} mac {$clientmac}"); else mwexec("/sbin/ipfw table 2 add {$clientip}"); @@ -411,8 +406,10 @@ function portal_allow($clientip,$clientmac,$username,$password = null, $attribut if ($captiveshouldunlock == true) unlock($cplock); - if ($writecfg == true) + if ($writecfg == true) { write_config(); + captiveportal_passthrumac_configure(true); + } /* redirect user to desired destination */ if ($url_redirection) diff --git a/usr/local/www/services_captiveportal_ip_edit.php b/usr/local/www/services_captiveportal_ip_edit.php index 4e1b661..977ba9f 100755 --- a/usr/local/www/services_captiveportal_ip_edit.php +++ b/usr/local/www/services_captiveportal_ip_edit.php @@ -118,7 +118,21 @@ if ($_POST) { write_config(); if (isset($config['captiveportal']['enable'])) { - mwexec("/sbin/ipfw table 1 add " . $ip['ip']); + $bwup = ""; + $bwdown = ""; + $ruleno = captiveportal_get_next_ipfw_ruleno(); + if (!empty($ip['bw_up'])) { + $pipeno = $ruleno + 20000; + mwexec("/sbin/ipfw pipe {$pipeno} config bw {$ip['bw_up']}Kbit/s queue 100") + $bwup = "pipe {$pipeno}"; + } + if (!empty($ip['bw_down'])) { + $pipeno = $ruleno + 20001; + mwexec("/sbin/ipfw pipe {$pipeno} config bw {$ip['bw_down']}Kbit/s queue 100") + $bwdown = "pipe {$pipeno}"; + } + mwexec("/sbin/ipfw table 1 add {$ip['ip']} {$bwup}"); + mwexec("/sbin/ipfw table 2 add {$ip['ip']} {$bwdown}"); } header("Location: services_captiveportal_ip.php"); diff --git a/usr/local/www/services_captiveportal_mac.php b/usr/local/www/services_captiveportal_mac.php index ca900bf..b689a81 100755 --- a/usr/local/www/services_captiveportal_mac.php +++ b/usr/local/www/services_captiveportal_mac.php @@ -59,8 +59,8 @@ if ($_POST) { $retval = 0; $rules = captiveportal_passthrumac_configure(); - file_put_contents("{$g['tmp_path']}/passthru.mac", $rules); - mwexec("/sbin/ipfw {$g['tmp_path']}/passthru.mac"); + //file_put_contents("{$g['tmp_path']}/passthru.mac", $rules); + //mwexec("/sbin/ipfw {$g['tmp_path']}/passthru.mac"); $savemsg = get_std_save_message($retval); if ($retval == 0) @@ -80,7 +80,7 @@ if ($_GET['act'] == "del") { unset($a_passthrumacs[$_GET['id']]); write_config(); header("Location: services_captiveportal_mac.php"); - //mark_subsystem_dirty('passthrumac'); + mark_subsystem_dirty('passthrumac'); exit; } } diff --git a/usr/local/www/services_captiveportal_mac_edit.php b/usr/local/www/services_captiveportal_mac_edit.php index f618d47..70049cd 100755 --- a/usr/local/www/services_captiveportal_mac_edit.php +++ b/usr/local/www/services_captiveportal_mac_edit.php @@ -120,7 +120,7 @@ if ($_POST) { write_config(); - //mark_subsystem_dirty('passthrumac'); + mark_subsystem_dirty('passthrumac'); header("Location: services_captiveportal_mac.php"); exit; |