Deprecated: The each() function is deprecated. This message will be suppressed on further calls in /home/zhenxiangba/zhenxiangba.com/public_html/phproxy-improved-master/index.php on line 456
# -*- shell-script -*-
# Ver.0.3.0
function cidr2oct () {
# Convert CIDR netmask to x.x.x.x format.
local mask bit octs i
mask=$1
if grep -q '\.' <<<$mask; then
echo $mask
return
fi
for ((i=$mask; $i>0; i--)); do
bit="${bit}1"
done
i=$((32 - $mask))
for ((i=$i; $i>0; i--)); do
bit="${bit}0"
done
octs=$(echo 'ibase=2;obase=A;'$(cut -c 1-8 <<<$bit) |bc)
octs=${octs}.$(echo 'ibase=2;obase=A;'$(cut -c 9-16 <<<$bit) |bc)
octs=${octs}.$(echo 'ibase=2;obase=A;'$(cut -c 17-24 <<<$bit) |bc)
octs=${octs}.$(echo 'ibase=2;obase=A;'$(cut -c 25-32 <<<$bit) |bc)
echo $octs
}
function oct2cidr () {
# Convert decimal netmask to CIDR.
local mask bit cidr i
mask=$1
if grep -qv '\.' <<<$mask; then
echo $mask
return
fi
for i in 1 2 3 4; do
bit=${bit}$(printf "%08d" \
$(echo 'ibase=10;obase=2;'$(cut -d '.' -f $i <<<$mask) |bc))
done
cidr=$(echo -n ${bit%%0*} |wc -m)
echo $cidr
}
function set_virnet_vars () {
## Auto-detect VirtNet specifications.
local i j addr net fwdmode fwddev br
#local mask
virbr_active=($(virnetinfo.py list))
i=0; j=0
for net in ${virbr_active[@]}; do
fwdmode=$(virnetinfo.py fwdmode $net)
br=$(virnetinfo.py brname $net)
if [ "$fwdmode" = "Unknown" ]; then
virbr_no_nat[i]=$br
: $((i+=1))
continue
fi
virbrnet_nat[j]=$(ip route show dev $br proto kernel |cut -d' ' -f1)
## Another way to learn virbrnet_nat, but this needs ipcalc.
#read addr mask < <(virnetinfo.py addr $net)
#mask=$(oct2cidr $mask |cut -d'=' -f2)
#virbrnet_nat[j]=$(ipcalc -s -n ${addr}/${mask} |cut -d'=' -f2)/$mask
addr=""
fwddev=$(virnetinfo.py fwddev $net)
if [ "$fwddev" = "Unknown" ]; then
fwddev=$(ip route show 0/0 |cut -d' ' -f5)
fi
addr=$(echo $(ip addr show dev $fwddev |grep inet) | \
cut -d' ' -f2)
peth_addr[j]=${addr%%/*}
: $((j+=1))
done
}
function disable_ipfwd () {
## Disable kernel IP forwarding if there is no NAT bridges.
if [ ${#virbr_no_nat[@]} -gt 0 -a ${#virbrnet_nat[@]} -lt 1 ]; then
echo 0 >/proc/sys/net/ipv4/ip_forward
fi
}
function is_validline () {
## FALSE if it seems a comment or blank line, TRUE otherwise.
grep -Eq '^[[:space:]]*(#|$)' <<<$1 && return 1
return 0
}
function set_route () {
## Add or replace routing tables.
## Arg: a file describing routes and/or rules.
local line
[ -r "$1" ] || return
while read line; do
if is_validline $line; then
if grep -Eq '^([0-9]|default)' <<<$line; then
ip route replace $line
continue
fi
ip rule add $line
fi
done < "$1"
}
function optimize_ipt () {
## Iptables optimization.
local i net rule omatch rulenum iface
# Replace MASQUERADE with SNAT rule.
if [ ${#virbrnet_nat[@]} -gt 0 ]; then
for i in $(seq 0 $((${#peth_addr[@]} - 1))); do
echo ${peth_addr[$i]} |grep -Eq '^([0-9]{1,3}\.){3}[0-9]{1,3}$'
[ $? -eq 0 ] || continue
net=${virbrnet_nat[$i]}
rule=$(iptables-save |grep MASQUERADE |
grep -F -e "-s ${net%%/*}/$(cidr2oct ${net##*/})" |head -n 1)
[ -z "$rule" ] && continue
omatch=$(echo "$rule" |sed 's/.*\(-o \w\+\).*/\1/' 2>/dev/null)
rulenum=$(iptables -t nat -L -n --line-numbers |
awk -v n=${net%%/*}/$(oct2cidr ${net##*/}) '{
if($2 == "MASQUERADE" && $5 == n){ print $1; exit; }
}')
iptables -t nat -R POSTROUTING $rulenum \
-s $net -d ! $net $omatch -j SNAT --to-source ${peth_addr[$i]}
done
fi
# Delete unnecessary DNS and DHCP rules.
for iface in ${virbr_no_nat[@]}; do
iptables -D INPUT \
-i $iface -p udp -m udp --dport 53 -j ACCEPT &>/dev/null
iptables -D INPUT \
-i $iface -p tcp -m tcp --dport 53 -j ACCEPT &>/dev/null
iptables -D INPUT \
-i $iface -p udp -m udp --dport 67 -j ACCEPT &>/dev/null
iptables -D INPUT \
-i $iface -p tcp -m tcp --dport 67 -j ACCEPT &>/dev/null
done
}