diff options
Diffstat (limited to 'src/etc/rc.kill_states')
-rwxr-xr-x | src/etc/rc.kill_states | 94 |
1 files changed, 94 insertions, 0 deletions
diff --git a/src/etc/rc.kill_states b/src/etc/rc.kill_states new file mode 100755 index 0000000..715c860 --- /dev/null +++ b/src/etc/rc.kill_states @@ -0,0 +1,94 @@ +#!/usr/local/bin/php-cgi -f +<?php +/* + rc.kill_states + Copyright (C) 2013 Renato Botelho (garga@pfsense.org) + part of pfSense (https://www.pfsense.org) + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS 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. +*/ + +/* parse the configuration and include all functions used below */ +require_once("globals.inc"); +require_once("config.inc"); +require_once("interfaces.inc"); +require_once("util.inc"); + +// Do not process while booting +if (platform_booting()) { + return; +} + +/* Interface address to cleanup states */ +$interface = str_replace("\n", "", $argv[1]); + +/* IP address to cleanup states */ +$local_ip = str_replace("\n", "", $argv[2]); + +if (empty($interface) || !does_interface_exist($interface)) { + log_error("rc.kill_states: Invalid interface '{$interface}'"); + return; +} + +if (!empty($local_ip)) { + list($local_ip, $subnet_bits) = explode("/", $local_ip); + + if (empty($subnet_bits)) { + $subnet_bits = "32"; + } + + if (!is_ipaddr($local_ip)) { + log_error("rc.kill_states: Invalid IP address '{$local_ip}'"); + return; + } +} + +if (!isset($config['system']['kill_states'])) { + if (!empty($local_ip)) { + log_error("rc.kill_states: Removing states for IP {$local_ip}/{$subnet_bits}"); + $nat_states = exec_command("/sbin/pfctl -i {$interface} -ss | " . + "/usr/bin/egrep '\-> +{$local_ip}:[0-9]+ +\->'"); + + $cleared_states = array(); + foreach (explode("\n", $nat_states) as $nat_state) { + if (preg_match_all('/([\d\.]+):[\d]+[\s->]+/i', $nat_state, $matches, PREG_SET_ORDER) != 3) { + continue; + } + + $src = $matches[0][1]; + $dst = $matches[2][1]; + + if (empty($src) || empty($dst) || in_array("{$src},{$dst}", $cleared_states)) { + continue; + } + + $cleared_states[] = "{$src},{$dst}"; + pfSense_kill_states($src, $dst); + } + + pfSense_kill_states("0.0.0.0/0", "{$local_ip}/{$subnet_bits}"); + pfSense_kill_states("{$local_ip}/{$subnet_bits}"); + pfSense_kill_srcstates("{$local_ip}/{$subnet_bits}"); + } + log_error("rc.kill_states: Removing states for interface {$interface}"); + mwexec("/sbin/pfctl -i {$interface} -Fs", true); +} |