mirror of
https://github.com/kenzok8/small-package
synced 2025-01-05 11:36:47 +08:00
update 2024-05-11 00:21:41
This commit is contained in:
parent
5ff6b359e9
commit
35a624a298
@ -5,12 +5,12 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=brook
|
||||
PKG_VERSION:=20240404
|
||||
PKG_VERSION:=20240606
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/txthinking/brook/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=6eda9a348f9c3555a1c27711e81c0982ea9999bf2878e73cf2eaaee90e8cc2e7
|
||||
PKG_HASH:=eee1c6173daff3199c23396f4661d7f81d701dc0f4eb1662b39041a6ca10703b
|
||||
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
|
@ -8,12 +8,10 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mwan3
|
||||
PKG_VERSION:=2.11.7
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>, \
|
||||
Aaron Goodman <aaronjg@alumni.stanford.edu>
|
||||
PKG_VERSION:=2.8.8
|
||||
PKG_RELEASE:=2
|
||||
PKG_MAINTAINER:=Florian Eckert <fe@dev.tdt.de>
|
||||
PKG_LICENSE:=GPL-2.0
|
||||
PKG_CONFIG_DEPENDS:=CONFIG_IPV6
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
@ -25,7 +23,6 @@ define Package/mwan3
|
||||
+ip \
|
||||
+ipset \
|
||||
+iptables \
|
||||
+IPV6:ip6tables \
|
||||
+iptables-mod-conntrack-extra \
|
||||
+iptables-mod-ipopt \
|
||||
+jshn
|
||||
@ -45,9 +42,12 @@ define Package/mwan3/conffiles
|
||||
/etc/mwan3.user
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/mwan3/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ] && [ -x /etc/init.d/rpcd ]; then
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
/etc/init.d/rpcd restart
|
||||
fi
|
||||
exit 0
|
||||
@ -55,63 +55,14 @@ endef
|
||||
|
||||
define Package/mwan3/postrm
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ] && [ -x /etc/init.d/rpcd ]; then
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
/etc/init.d/rpcd restart
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(TARGET_CC) $(CFLAGS) $(LDFLAGS) $(FPIC) \
|
||||
-shared \
|
||||
-o $(PKG_BUILD_DIR)/libwrap_mwan3_sockopt.so.1.0 \
|
||||
$(if $(CONFIG_IPV6),-DCONFIG_IPV6) \
|
||||
$(PKG_BUILD_DIR)/sockopt_wrap.c \
|
||||
-ldl
|
||||
endef
|
||||
|
||||
define Package/mwan3/install
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./files/etc/config/mwan3 \
|
||||
$(1)/etc/config/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_DATA) ./files/etc/hotplug.d/iface/15-mwan3 \
|
||||
$(1)/etc/hotplug.d/iface/
|
||||
$(INSTALL_DATA) ./files/etc/hotplug.d/iface/16-mwan3-user \
|
||||
$(1)/etc/hotplug.d/iface/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/etc/init.d/mwan3 \
|
||||
$(1)/etc/init.d/
|
||||
|
||||
$(INSTALL_DIR) $(1)/lib/mwan3
|
||||
$(INSTALL_DATA) ./files/lib/mwan3/common.sh \
|
||||
$(1)/lib/mwan3/
|
||||
$(INSTALL_DATA) ./files/lib/mwan3/mwan3.sh \
|
||||
$(1)/lib/mwan3/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/libexec/rpcd
|
||||
$(INSTALL_BIN) ./files/usr/libexec/rpcd/mwan3 \
|
||||
$(1)/usr/libexec/rpcd/
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) ./files/usr/sbin/mwan3 \
|
||||
$(1)/usr/sbin/
|
||||
$(INSTALL_BIN) ./files/usr/sbin/mwan3rtmon \
|
||||
$(1)/usr/sbin/
|
||||
$(INSTALL_BIN) ./files/usr/sbin/mwan3track \
|
||||
$(1)/usr/sbin/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc
|
||||
$(INSTALL_BIN) ./files/etc/mwan3.user \
|
||||
$(1)/etc/
|
||||
|
||||
$(CP) $(PKG_BUILD_DIR)/libwrap_mwan3_sockopt.so.1.0 $(1)/lib/mwan3/
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_DATA) ./files/etc/uci-defaults/mwan3-migrate-flush_conntrack \
|
||||
$(1)/etc/uci-defaults/
|
||||
$(CP) ./files/* $(1)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,mwan3))
|
||||
|
@ -1,6 +1,7 @@
|
||||
|
||||
config globals 'globals'
|
||||
option mmx_mask '0x3F00'
|
||||
option rtmon_interval '5'
|
||||
|
||||
config member 'wan_m1_w3'
|
||||
option interface 'wan'
|
||||
|
@ -3,87 +3,92 @@
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
. /usr/share/libubox/jshn.sh
|
||||
|
||||
initscript=/etc/init.d/mwan3
|
||||
. /lib/functions/procd.sh
|
||||
|
||||
|
||||
SCRIPTNAME="mwan3-hotplug"
|
||||
[ "$ACTION" = "ifup" ] || [ "$ACTION" = "ifdown" ] || [ "$ACTION" = "connected" ] || [ "$ACTION" = "disconnected" ] || exit 1
|
||||
[ "$ACTION" == "ifup" -o "$ACTION" == "ifdown" ] || exit 1
|
||||
[ -n "$INTERFACE" ] || exit 2
|
||||
[ "$FIRSTCONNECT" = "1" ] || [ "$MWAN3_SHUTDOWN" = "1" ] && exit 0
|
||||
|
||||
if { [ "$ACTION" = "ifup" ] || [ "$ACTION" = "connected" ] ; } && [ -z "$DEVICE" ]; then
|
||||
LOG notice "$ACTION called on $INTERFACE with no device set"
|
||||
exit 3
|
||||
if [ "$ACTION" == "ifup" ]; then
|
||||
[ -n "$DEVICE" ] || exit 3
|
||||
fi
|
||||
|
||||
[ "$MWAN3_STARTUP" = "init" ] || procd_lock
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' '0'
|
||||
[ ${enabled} -gt 0 ] || exit 0
|
||||
|
||||
mwan3_lock "$ACTION" "$INTERFACE"
|
||||
mwan3_init
|
||||
mwan3_set_connected_iptables
|
||||
mwan3_set_custom_ipset
|
||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
|
||||
/etc/init.d/mwan3 running || {
|
||||
[ "$MWAN3_STARTUP" = "init" ] || procd_lock
|
||||
LOG notice "mwan3 hotplug $ACTION on $INTERFACE not called because globally disabled"
|
||||
exit 0
|
||||
}
|
||||
config_get enabled $INTERFACE enabled 0
|
||||
config_get initial_state $INTERFACE initial_state "online"
|
||||
[ "$enabled" == "1" ] || exit 0
|
||||
|
||||
$IPT4 -S mwan3_hook &>/dev/null || {
|
||||
LOG warn "hotplug called on $INTERFACE before mwan3 has been set up"
|
||||
exit 0
|
||||
}
|
||||
|
||||
if [ "$MWAN3_STARTUP" != "init" ] && [ "$ACTION" = "ifup" ]; then
|
||||
mwan3_set_user_iface_rules $INTERFACE $DEVICE
|
||||
if [ "$ACTION" == "ifup" ]; then
|
||||
config_get family $INTERFACE family ipv4
|
||||
if [ "$family" = "ipv4" ]; then
|
||||
ubus call network.interface.${INTERFACE}_4 status &>/dev/null
|
||||
if [ "$?" -eq "0" ]; then
|
||||
network_get_ipaddr src_ip ${INTERFACE}_4
|
||||
else
|
||||
network_get_ipaddr src_ip ${INTERFACE}
|
||||
fi
|
||||
[ -n "$src_ip" ] || src_ip="0.0.0.0"
|
||||
elif [ "$family" = "ipv6" ]; then
|
||||
ubus call network.interface.${INTERFACE}_6 status &>/dev/null
|
||||
if [ "$?" -eq "0" ]; then
|
||||
network_get_ipaddr6 src_ip ${INTERFACE}_6
|
||||
else
|
||||
network_get_ipaddr6 src_ip ${INTERFACE}
|
||||
fi
|
||||
[ -n "$src_ip" ] || src_ip="::"
|
||||
fi
|
||||
fi
|
||||
|
||||
config_get_bool enabled $INTERFACE 'enabled' '0'
|
||||
[ "${enabled}" -eq 1 ] || {
|
||||
LOG notice "mwan3 hotplug on $INTERFACE not called because interface disabled"
|
||||
exit 0
|
||||
}
|
||||
|
||||
config_get initial_state $INTERFACE initial_state "online"
|
||||
if [ "$initial_state" = "offline" ]; then
|
||||
status=$(cat $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS 2>/dev/null || echo unknown)
|
||||
[ "$status" = "online" ] || status=offline
|
||||
json_load "$(ubus call mwan3 status '{"section":"interfaces"}')"
|
||||
json_select "interfaces"
|
||||
json_select "${INTERFACE}"
|
||||
json_get_var running running
|
||||
json_get_var status status
|
||||
else
|
||||
status=online
|
||||
running=1
|
||||
fi
|
||||
|
||||
LOG notice "Execute $ACTION event on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
mwan3_lock "$ACTION" "$INTERFACE"
|
||||
$LOG notice "Execute "$ACTION" event on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
|
||||
case "$ACTION" in
|
||||
connected)
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "online"
|
||||
mwan3_set_policies_iptables
|
||||
;;
|
||||
ifup)
|
||||
mwan3_set_general_rules
|
||||
mwan3_set_general_iptables
|
||||
mwan3_create_iface_iptables $INTERFACE $DEVICE
|
||||
mwan3_create_iface_rules $INTERFACE $DEVICE
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "$status"
|
||||
if [ "$MWAN3_STARTUP" != "init" ]; then
|
||||
mwan3_create_iface_route $INTERFACE $DEVICE
|
||||
mwan3_set_general_rules
|
||||
[ "$status" = "online" ] && mwan3_set_policies_iptables
|
||||
mwan3_create_iface_route $INTERFACE $DEVICE
|
||||
if [ ${running} -eq 1 -a "${status}" = "online" ]; then
|
||||
$LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "online"
|
||||
mwan3_track $INTERFACE $DEVICE "online" "$src_ip"
|
||||
else
|
||||
$LOG notice "Starting tracker on interface $INTERFACE (${DEVICE:-unknown})"
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
||||
mwan3_track $INTERFACE $DEVICE "offline" "$src_ip"
|
||||
fi
|
||||
[ "$ACTION" = ifup ] && procd_running mwan3 "track_$INTERFACE" && procd_send_signal mwan3 "track_$INTERFACE" USR2
|
||||
;;
|
||||
disconnected)
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
||||
mwan3_set_policies_iptables
|
||||
;;
|
||||
mwan3_set_user_rules
|
||||
;;
|
||||
ifdown)
|
||||
mwan3_set_iface_hotplug_state $INTERFACE "offline"
|
||||
mwan3_delete_iface_ipset_entries $INTERFACE
|
||||
mwan3_delete_iface_rules $INTERFACE
|
||||
mwan3_delete_iface_route $INTERFACE
|
||||
mwan3_delete_iface_iptables $INTERFACE
|
||||
procd_running mwan3 "track_$INTERFACE" && procd_send_signal mwan3 "track_$INTERFACE" USR1
|
||||
mwan3_track_signal $INTERFACE $DEVICE
|
||||
mwan3_set_policies_iptables
|
||||
mwan3_set_user_rules
|
||||
;;
|
||||
esac
|
||||
|
||||
mwan3_flush_conntrack "$INTERFACE" "$ACTION"
|
||||
mwan3_unlock "$ACTION" "$INTERFACE"
|
||||
|
||||
exit 0
|
||||
|
22
mwan3/files/etc/hotplug.d/iface/16-mwan3
Normal file
22
mwan3/files/etc/hotplug.d/iface/16-mwan3
Normal file
@ -0,0 +1,22 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' '0'
|
||||
[ ${enabled} -gt 0 ] || exit 0
|
||||
|
||||
if [ "$ACTION" == "ifup" ]; then
|
||||
mwan3_lock "$ACTION" "mwan3rtmon"
|
||||
mwan3_rtmon
|
||||
mwan3_unlock "$ACTION" "mwan3rtmon"
|
||||
fi
|
||||
|
||||
config_get enabled $INTERFACE enabled 0
|
||||
[ "${enabled}" = "0" ] || {
|
||||
mwan3_flush_conntrack "$INTERFACE" "$ACTION"
|
||||
}
|
||||
|
||||
exit 0
|
@ -2,25 +2,15 @@
|
||||
|
||||
[ -f "/etc/mwan3.user" ] && {
|
||||
. /lib/functions.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
initscript=/etc/init.d/mwan3
|
||||
. /lib/functions/procd.sh
|
||||
|
||||
[ "$MWAN3_SHUTDOWN" != 1 ] && procd_lock
|
||||
|
||||
[ "$MWAN3_SHUTDOWN" != 1 ] && ! /etc/init.d/mwan3 running && {
|
||||
exit 0
|
||||
}
|
||||
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' '0'
|
||||
[ ${enabled} -gt 0 ] || exit 0
|
||||
|
||||
config_get_bool enabled "$INTERFACE" enabled 0
|
||||
[ "${enabled}" -eq 1 ] || {
|
||||
exit 0
|
||||
}
|
||||
|
||||
[ -x /etc/mwan3.user ] || chmod 755 /etc/mwan3.user
|
||||
env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /etc/mwan3.user
|
||||
config_get enabled "$INTERFACE" enabled 0
|
||||
[ "${enabled}" = "1" ] || exit 0
|
||||
env -i ACTION="$ACTION" INTERFACE="$INTERFACE" DEVICE="$DEVICE" \
|
||||
/bin/sh /etc/mwan3.user
|
||||
}
|
||||
|
||||
exit 0
|
||||
|
113
mwan3/files/etc/init.d/mwan3
Normal file → Executable file
113
mwan3/files/etc/init.d/mwan3
Normal file → Executable file
@ -1,109 +1,26 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
. "${IPKG_INSTROOT}/lib/functions/network.sh"
|
||||
. "${IPKG_INSTROOT}/lib/mwan3/mwan3.sh"
|
||||
|
||||
START=19
|
||||
USE_PROCD=1
|
||||
SCRIPTNAME="mwan3-init"
|
||||
|
||||
service_running() {
|
||||
[ -d "$MWAN3_STATUS_DIR" ]
|
||||
}
|
||||
|
||||
start_tracker() {
|
||||
local enabled interface
|
||||
interface=$1
|
||||
config_get_bool enabled $interface 'enabled' '0'
|
||||
[ $enabled -eq 0 ] && return
|
||||
[ -z "$(config_get $interface track_ip)" ] && return
|
||||
|
||||
procd_open_instance "track_${1}"
|
||||
procd_set_param command /usr/sbin/mwan3track $interface
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
start_service() {
|
||||
local enabled hotplug_pids
|
||||
|
||||
mwan3_init
|
||||
config_foreach start_tracker interface
|
||||
|
||||
mwan3_update_iface_to_table
|
||||
mwan3_set_dynamic_ipset
|
||||
mwan3_set_connected_ipset
|
||||
mwan3_set_custom_ipset
|
||||
mwan3_set_general_rules
|
||||
mwan3_set_general_iptables
|
||||
config_foreach mwan3_ifup interface "init"
|
||||
wait $hotplug_pids
|
||||
mwan3_set_policies_iptables
|
||||
mwan3_set_user_rules
|
||||
|
||||
procd_open_instance rtmon_ipv4
|
||||
procd_set_param command /usr/sbin/mwan3rtmon ipv4
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
|
||||
if command -v ip6tables > /dev/null; then
|
||||
procd_open_instance rtmon_ipv6
|
||||
procd_set_param command /usr/sbin/mwan3rtmon ipv6
|
||||
procd_set_param respawn
|
||||
procd_close_instance
|
||||
fi
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
local ipset rule IP IPTR IPT family table tid
|
||||
|
||||
mwan3_init
|
||||
config_foreach mwan3_interface_shutdown interface
|
||||
|
||||
for family in ipv4 ipv6; do
|
||||
if [ "$family" = "ipv4" ]; then
|
||||
IPT="$IPT4"
|
||||
IPTR="$IPT4R"
|
||||
IP="$IP4"
|
||||
elif [ "$family" = "ipv6" ]; then
|
||||
[ $NO_IPV6 -ne 0 ] && continue
|
||||
IPT="$IPT6"
|
||||
IPTR="$IPT6R"
|
||||
IP="$IP6"
|
||||
fi
|
||||
|
||||
for tid in $($IP route list table all | sed -ne 's/.*table \([0-9]\+\).*/\1/p' | sort -u); do
|
||||
[ $tid -gt $MWAN3_INTERFACE_MAX ] && continue
|
||||
$IP route flush table $tid &> /dev/null
|
||||
done
|
||||
|
||||
for rule in $($IP rule list | grep -E '^[1-3][0-9]{3}\:' | cut -d ':' -f 1); do
|
||||
$IP rule del pref $rule &> /dev/null
|
||||
done
|
||||
table="$($IPT -S)"
|
||||
{
|
||||
echo "*mangle";
|
||||
[ -z "${table##*PREROUTING -j mwan3_hook*}" ] && echo "-D PREROUTING -j mwan3_hook"
|
||||
[ -z "${table##*OUTPUT -j mwan3_hook*}" ] && echo "-D OUTPUT -j mwan3_hook"
|
||||
echo "$table" | awk '{print "-F "$2}' | grep mwan3 | sort -u
|
||||
echo "$table" | awk '{print "-X "$2}' | grep mwan3 | sort -u
|
||||
echo "COMMIT"
|
||||
} | $IPTR
|
||||
done
|
||||
|
||||
# Needed for the firewall backend to release the ipsets reference
|
||||
sleep 2
|
||||
for ipset in $($IPS -n list | grep mwan3_); do
|
||||
$IPS -q destroy $ipset
|
||||
done
|
||||
|
||||
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
|
||||
|
||||
boot() {
|
||||
. /lib/config/uci.sh
|
||||
uci_toggle_state mwan3 globals enabled "1"
|
||||
mwan3_boot=1
|
||||
rc_procd start_service
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
stop
|
||||
start
|
||||
/usr/sbin/mwan3 restart
|
||||
}
|
||||
|
||||
start_service() {
|
||||
[ -n "${mwan3_boot}" ] && return 0
|
||||
/usr/sbin/mwan3 start
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
/usr/sbin/mwan3 stop
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
|
@ -8,13 +8,9 @@
|
||||
# There are three main environment variables that are passed to this script.
|
||||
#
|
||||
# $ACTION
|
||||
# <ifup> Is called by netifd and mwan3track.
|
||||
# <ifdown> Is called by netifd and mwan3track.
|
||||
# <connected> Is only called by mwan3track if tracking was successful.
|
||||
# <disconnected> Is only called by mwan3track if tracking has failed.
|
||||
# $INTERFACE Name of the interface an action relates to (e.g. "wan" or "wwan").
|
||||
# $DEVICE Physical device name of the interface the action relates to (e.g. "eth0" or "wwan0").
|
||||
# Note: On an ifdown event, $DEVICE is not available, use $INTERFACE instead.
|
||||
#
|
||||
# Further documentation can be found here:
|
||||
# https://openwrt.org/docs/guide-user/network/wan/multiwan/mwan3#alertsnotifications
|
||||
# <ifup> Is called by netifd and mwan3track
|
||||
# <ifdown> Is called by netifd and mwan3track
|
||||
# <connected> Is only called by mwan3track if tracking was successful
|
||||
# <disconnected> Is only called by mwan3track if tracking has failed
|
||||
# $INTERFACE Name of the interface which went up or down (e.g. "wan" or "wwan")
|
||||
# $DEVICE Physical device name which interface went up or down (e.g. "eth0" or "wwan0")
|
||||
|
@ -1,205 +1,6 @@
|
||||
#!/bin/sh
|
||||
|
||||
IP4="ip -4"
|
||||
IP6="ip -6"
|
||||
SCRIPTNAME="$(basename "$0")"
|
||||
|
||||
MWAN3_STATUS_DIR="/var/run/mwan3"
|
||||
MWAN3_STATUS_IPTABLES_LOG_DIR="${MWAN3_STATUS_DIR}/iptables_log"
|
||||
MWAN3TRACK_STATUS_DIR="/var/run/mwan3track"
|
||||
|
||||
MWAN3_INTERFACE_MAX=""
|
||||
|
||||
MMX_MASK=""
|
||||
MMX_DEFAULT=""
|
||||
MMX_BLACKHOLE=""
|
||||
MM_BLACKHOLE=""
|
||||
|
||||
MMX_UNREACHABLE=""
|
||||
MM_UNREACHABLE=""
|
||||
MAX_SLEEP=$(((1<<31)-1))
|
||||
|
||||
command -v ip6tables > /dev/null
|
||||
NO_IPV6=$?
|
||||
|
||||
IPS="ipset"
|
||||
IPT4="iptables -t mangle -w"
|
||||
IPT6="ip6tables -t mangle -w"
|
||||
IPT4R="iptables-restore -T mangle -w -n"
|
||||
IPT6R="ip6tables-restore -T mangle -w -n"
|
||||
|
||||
LOG()
|
||||
{
|
||||
local facility=$1; shift
|
||||
# in development, we want to show 'debug' level logs
|
||||
# when this release is out of beta, the comment in the line below
|
||||
# should be removed
|
||||
[ "$facility" = "debug" ] && return
|
||||
logger -t "${SCRIPTNAME}[$$]" -p $facility "$*"
|
||||
}
|
||||
|
||||
mwan3_get_true_iface()
|
||||
{
|
||||
local family V
|
||||
_true_iface=$2
|
||||
config_get family "$2" family ipv4
|
||||
if [ "$family" = "ipv4" ]; then
|
||||
V=4
|
||||
elif [ "$family" = "ipv6" ]; then
|
||||
V=6
|
||||
fi
|
||||
ubus call "network.interface.${2}_${V}" status &>/dev/null && _true_iface="${2}_${V}"
|
||||
export "$1=$_true_iface"
|
||||
}
|
||||
|
||||
mwan3_get_src_ip()
|
||||
{
|
||||
local family _src_ip interface true_iface device addr_cmd default_ip IP sed_str
|
||||
interface=$2
|
||||
mwan3_get_true_iface true_iface $interface
|
||||
|
||||
unset "$1"
|
||||
config_get family "$interface" family ipv4
|
||||
if [ "$family" = "ipv4" ]; then
|
||||
addr_cmd='network_get_ipaddr'
|
||||
default_ip="0.0.0.0"
|
||||
sed_str='s/ *inet \([^ \/]*\).*/\1/;T; pq'
|
||||
IP="$IP4"
|
||||
elif [ "$family" = "ipv6" ]; then
|
||||
addr_cmd='network_get_ipaddr6'
|
||||
default_ip="::"
|
||||
sed_str='s/ *inet6 \([^ \/]*\).* scope.*/\1/;T; pq'
|
||||
IP="$IP6"
|
||||
fi
|
||||
|
||||
$addr_cmd _src_ip "$true_iface"
|
||||
if [ -z "$_src_ip" ]; then
|
||||
network_get_device device $true_iface
|
||||
_src_ip=$($IP address ls dev $device 2>/dev/null | sed -ne "$sed_str")
|
||||
if [ -n "$_src_ip" ]; then
|
||||
LOG warn "no src $family address found from netifd for interface '$true_iface' dev '$device' guessing $_src_ip"
|
||||
else
|
||||
_src_ip="$default_ip"
|
||||
LOG warn "no src $family address found for interface '$true_iface' dev '$device'"
|
||||
fi
|
||||
fi
|
||||
export "$1=$_src_ip"
|
||||
}
|
||||
|
||||
mwan3_get_mwan3track_status()
|
||||
{
|
||||
local track_ips pid
|
||||
mwan3_list_track_ips()
|
||||
{
|
||||
track_ips="$1 $track_ips"
|
||||
}
|
||||
config_list_foreach "$1" track_ip mwan3_list_track_ips
|
||||
|
||||
if [ -n "$track_ips" ]; then
|
||||
pid="$(pgrep -f "mwan3track $1$")"
|
||||
if [ -n "$pid" ]; then
|
||||
if [ "$(cat /proc/"$(pgrep -P $pid)"/cmdline)" = "sleep${MAX_SLEEP}" ]; then
|
||||
tracking="paused"
|
||||
else
|
||||
tracking="active"
|
||||
fi
|
||||
else
|
||||
tracking="down"
|
||||
fi
|
||||
else
|
||||
tracking="not enabled"
|
||||
fi
|
||||
echo "$tracking"
|
||||
}
|
||||
|
||||
mwan3_init()
|
||||
{
|
||||
local bitcnt mmdefault source_routing
|
||||
|
||||
config_load mwan3
|
||||
|
||||
[ -d $MWAN3_STATUS_DIR ] || mkdir -p $MWAN3_STATUS_DIR/iface_state
|
||||
[ -d "$MWAN3_STATUS_IPTABLES_LOG_DIR" ] || mkdir -p "$MWAN3_STATUS_IPTABLES_LOG_DIR"
|
||||
|
||||
# mwan3's MARKing mask (at least 3 bits should be set)
|
||||
if [ -e "${MWAN3_STATUS_DIR}/mmx_mask" ]; then
|
||||
MMX_MASK=$(cat "${MWAN3_STATUS_DIR}/mmx_mask")
|
||||
MWAN3_INTERFACE_MAX=$(uci_get_state mwan3 globals iface_max)
|
||||
else
|
||||
config_get MMX_MASK globals mmx_mask '0x3F00'
|
||||
echo "$MMX_MASK"| tr 'A-F' 'a-f' > "${MWAN3_STATUS_DIR}/mmx_mask"
|
||||
LOG debug "Using firewall mask ${MMX_MASK}"
|
||||
|
||||
bitcnt=$(mwan3_count_one_bits MMX_MASK)
|
||||
mmdefault=$(((1<<bitcnt)-1))
|
||||
MWAN3_INTERFACE_MAX=$((mmdefault-3))
|
||||
uci_toggle_state mwan3 globals iface_max "$MWAN3_INTERFACE_MAX"
|
||||
LOG debug "Max interface count is ${MWAN3_INTERFACE_MAX}"
|
||||
fi
|
||||
|
||||
# remove "linkdown", expiry and source based routing modifiers from route lines
|
||||
config_get_bool source_routing globals source_routing 0
|
||||
[ $source_routing -eq 1 ] && unset source_routing
|
||||
MWAN3_ROUTE_LINE_EXP="s/offload//; s/linkdown //; s/expires [0-9]\+sec//; s/error [0-9]\+//; ${source_routing:+s/default\(.*\) from [^ ]*/default\1/;} p"
|
||||
|
||||
# mark mask constants
|
||||
bitcnt=$(mwan3_count_one_bits MMX_MASK)
|
||||
mmdefault=$(((1<<bitcnt)-1))
|
||||
MM_BLACKHOLE=$((mmdefault-2))
|
||||
MM_UNREACHABLE=$((mmdefault-1))
|
||||
|
||||
# MMX_DEFAULT should equal MMX_MASK
|
||||
MMX_DEFAULT=$(mwan3_id2mask mmdefault MMX_MASK)
|
||||
MMX_BLACKHOLE=$(mwan3_id2mask MM_BLACKHOLE MMX_MASK)
|
||||
MMX_UNREACHABLE=$(mwan3_id2mask MM_UNREACHABLE MMX_MASK)
|
||||
}
|
||||
|
||||
# maps the 1st parameter so it only uses the bits allowed by the bitmask (2nd parameter)
|
||||
# which means spreading the bits of the 1st parameter to only use the bits that are set to 1 in the 2nd parameter
|
||||
# 0 0 0 0 0 1 0 1 (0x05) 1st parameter
|
||||
# 1 0 1 0 1 0 1 0 (0xAA) 2nd parameter
|
||||
# 1 0 1 result
|
||||
mwan3_id2mask()
|
||||
{
|
||||
local bit_msk bit_val result
|
||||
bit_val=0
|
||||
result=0
|
||||
for bit_msk in $(seq 0 31); do
|
||||
if [ $((($2>>bit_msk)&1)) = "1" ]; then
|
||||
if [ $((($1>>bit_val)&1)) = "1" ]; then
|
||||
result=$((result|(1<<bit_msk)))
|
||||
fi
|
||||
bit_val=$((bit_val+1))
|
||||
fi
|
||||
done
|
||||
printf "0x%x" $result
|
||||
}
|
||||
|
||||
# counts how many bits are set to 1
|
||||
# n&(n-1) clears the lowest bit set to 1
|
||||
mwan3_count_one_bits()
|
||||
{
|
||||
local count n
|
||||
count=0
|
||||
n=$(($1))
|
||||
while [ "$n" -gt "0" ]; do
|
||||
n=$((n&(n-1)))
|
||||
count=$((count+1))
|
||||
done
|
||||
echo $count
|
||||
}
|
||||
|
||||
get_uptime() {
|
||||
local uptime=$(cat /proc/uptime)
|
||||
echo "${uptime%%.*}"
|
||||
}
|
||||
|
||||
get_online_time() {
|
||||
local time_n time_u iface
|
||||
iface="$1"
|
||||
time_u="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/ONLINE" 2>/dev/null)"
|
||||
[ -z "${time_u}" ] || [ "${time_u}" = "0" ] || {
|
||||
time_n="$(get_uptime)"
|
||||
echo $((time_n-time_u))
|
||||
}
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
126
mwan3/files/usr/libexec/rpcd/mwan3
Normal file → Executable file
126
mwan3/files/usr/libexec/rpcd/mwan3
Normal file → Executable file
@ -5,6 +5,12 @@
|
||||
. /usr/share/libubox/jshn.sh
|
||||
. /lib/mwan3/common.sh
|
||||
|
||||
MWAN3TRACK_STATUS_DIR="/var/run/mwan3track"
|
||||
|
||||
IPS="ipset"
|
||||
IPT4="iptables -t mangle -w"
|
||||
IPT6="ip6tables -t mangle -w"
|
||||
|
||||
report_connected_v4() {
|
||||
local address
|
||||
|
||||
@ -16,7 +22,6 @@ report_connected_v4() {
|
||||
}
|
||||
|
||||
report_connected_v6() {
|
||||
[ $NO_IPV6 -ne 0 ] && return
|
||||
local address
|
||||
|
||||
if [ -n "$($IPT6 -S mwan3_connected 2> /dev/null)" ]; then
|
||||
@ -55,7 +60,6 @@ report_policies_v4() {
|
||||
}
|
||||
|
||||
report_policies_v6() {
|
||||
[ $NO_IPV6 -ne 0 ] && return
|
||||
local policy
|
||||
|
||||
for policy in $($IPT6 -S | awk '{print $2}' | grep mwan3_policy_ | sort -u); do
|
||||
@ -65,26 +69,6 @@ report_policies_v6() {
|
||||
done
|
||||
}
|
||||
|
||||
get_age() {
|
||||
local time_p time_u
|
||||
iface="$1"
|
||||
time_p="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TIME")"
|
||||
[ -z "${time_p}" ] || {
|
||||
time_n="$(get_uptime)"
|
||||
echo $((time_n-time_p))
|
||||
}
|
||||
}
|
||||
|
||||
get_offline_time() {
|
||||
local time_n time_d iface
|
||||
iface="$1"
|
||||
time_d="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/OFFLINE")"
|
||||
[ -z "${time_d}" ] || [ "${time_d}" = "0" ] || {
|
||||
time_n="$(get_uptime)"
|
||||
echo $((time_n-time_d))
|
||||
}
|
||||
}
|
||||
|
||||
get_mwan3_status() {
|
||||
local iface="${1}"
|
||||
local iface_select="${2}"
|
||||
@ -92,60 +76,74 @@ get_mwan3_status() {
|
||||
local age=0
|
||||
local online=0
|
||||
local offline=0
|
||||
local enabled time_p time_n time_u time_d status track_status up uptime
|
||||
local up="0"
|
||||
local enabled pid device time_p time_n time_u time_d status
|
||||
|
||||
if [ "${iface}" != "${iface_select}" ] && [ "${iface_select}" != "" ]; then
|
||||
return
|
||||
fi
|
||||
network_get_device device $1
|
||||
|
||||
track_status="$(mwan3_get_mwan3track_status "$1")"
|
||||
[ "$track_status" = "active" ] && running="1"
|
||||
age=$(get_age "$iface")
|
||||
online=$(get_online_time "$iface")
|
||||
offline=$(get_offline_time "$iface")
|
||||
if [ "${iface}" = "${iface_select}" ] || [ "${iface_select}" = "" ]; then
|
||||
pid="$(pgrep -f "mwan3track $iface $device")"
|
||||
if [ "${pid}" != "" ]; then
|
||||
running="1"
|
||||
fi
|
||||
|
||||
config_get enabled "$iface" enabled 0
|
||||
time_p="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TIME")"
|
||||
[ -z "${time_p}" ] || {
|
||||
time_n="$(get_uptime)"
|
||||
let age=time_n-time_p
|
||||
}
|
||||
|
||||
if [ -d "${MWAN3_STATUS_DIR}" ]; then
|
||||
time_u="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/ONLINE")"
|
||||
[ -z "${time_u}" ] || [ "${time_u}" = "0" ] || {
|
||||
time_n="$(get_uptime)"
|
||||
let online=time_n-time_u
|
||||
}
|
||||
|
||||
time_d="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/OFFLINE")"
|
||||
[ -z "${time_d}" ] || [ "${time_d}" = "0" ] || {
|
||||
time_n="$(get_uptime)"
|
||||
let offline=time_n-time_d
|
||||
}
|
||||
|
||||
local uptime="0"
|
||||
|
||||
config_get enabled "$iface" enabled 0
|
||||
network_get_uptime uptime "$iface"
|
||||
network_is_up "$iface" && up="1"
|
||||
|
||||
if [ -f "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS" ]; then
|
||||
status="$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/STATUS")"
|
||||
else
|
||||
status="notracking"
|
||||
status="unknown"
|
||||
fi
|
||||
else
|
||||
uptime=0
|
||||
up=0
|
||||
status="unknown"
|
||||
fi
|
||||
|
||||
json_add_object "${iface}"
|
||||
json_add_int age "$age"
|
||||
json_add_int online "${online}"
|
||||
json_add_int offline "${offline}"
|
||||
json_add_int uptime "${uptime}"
|
||||
json_add_int "score" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/SCORE")"
|
||||
json_add_int "lost" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOST")"
|
||||
json_add_int "turn" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TURN")"
|
||||
json_add_string "status" "${status}"
|
||||
json_add_boolean "enabled" "${enabled}"
|
||||
json_add_boolean "running" "${running}"
|
||||
json_add_boolean "up" "${up}"
|
||||
json_add_array "track_ip"
|
||||
for file in $MWAN3TRACK_STATUS_DIR/${iface}/TRACK_*; do
|
||||
[ -z "${file#*/TRACK_OUTPUT}" ] && continue
|
||||
[ -z "${file#*/TRACK_\*}" ] && continue
|
||||
track="${file#*/TRACK_}"
|
||||
json_add_object
|
||||
json_add_string ip "${track}"
|
||||
json_add_string status "$(cat "${file}")"
|
||||
json_add_int latency "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LATENCY_${track}")"
|
||||
json_add_int packetloss "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOSS_${track}")"
|
||||
json_add_object "${iface}"
|
||||
json_add_int age "$age"
|
||||
json_add_int online "${online}"
|
||||
json_add_int offline "${offline}"
|
||||
json_add_int uptime "${uptime}"
|
||||
json_add_int "score" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/SCORE")"
|
||||
json_add_int "lost" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOST")"
|
||||
json_add_int "turn" "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/TURN")"
|
||||
json_add_string "status" "${status}"
|
||||
json_add_boolean "enabled" "${enabled}"
|
||||
json_add_boolean "running" "${running}"
|
||||
json_add_boolean "up" "${up}"
|
||||
json_add_array "track_ip"
|
||||
for file in $MWAN3TRACK_STATUS_DIR/${iface}/*; do
|
||||
track="${file#*/TRACK_}"
|
||||
if [ "${track}" != "${file}" ]; then
|
||||
json_add_object
|
||||
json_add_string ip "${track}"
|
||||
json_add_string status "$(cat "${file}")"
|
||||
json_add_int latency "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LATENCY_${track}")"
|
||||
json_add_int packetloss "$(cat "$MWAN3TRACK_STATUS_DIR/${iface}/LOSS_${track}")"
|
||||
json_close_object
|
||||
fi
|
||||
done
|
||||
json_close_array
|
||||
json_close_object
|
||||
done
|
||||
json_close_array
|
||||
json_close_object
|
||||
fi
|
||||
}
|
||||
|
||||
main () {
|
||||
|
270
mwan3/files/usr/sbin/mwan3
Normal file → Executable file
270
mwan3/files/usr/sbin/mwan3
Normal file → Executable file
@ -5,62 +5,75 @@
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
|
||||
command_help() {
|
||||
local cmd="$1"
|
||||
local help="$2"
|
||||
|
||||
echo "$(printf "%-25s%s" "${cmd}" "${help}")"
|
||||
}
|
||||
|
||||
help()
|
||||
{
|
||||
cat <<EOF
|
||||
Syntax: mwan3 [command]
|
||||
|
||||
Available commands:
|
||||
start Load iptables rules, ip rules and ip routes
|
||||
stop Unload iptables rules, ip rules and ip routes
|
||||
restart Reload iptables rules, ip rules and ip routes
|
||||
ifup <iface> Load rules and routes for specific interface
|
||||
ifdown <iface> Unload rules and routes for specific interface
|
||||
interfaces Show interfaces status
|
||||
policies Show currently active policy
|
||||
connected Show directly connected networks
|
||||
rules Show active rules
|
||||
status Show all status
|
||||
|
||||
EOF
|
||||
command_help "start" "Load iptables rules, ip rules and ip routes"
|
||||
command_help "stop" "Unload iptables rules, ip rules and ip routes"
|
||||
command_help "restart" "Reload iptables rules, ip rules and ip routes"
|
||||
command_help "ifup <iface>" "Load rules and routes for specific interface"
|
||||
command_help "ifdown <iface>" "Unload rules and routes for specific interface"
|
||||
command_help "interfaces" "Show interfaces status"
|
||||
command_help "policies" "Show currently active policy"
|
||||
command_help "connected" "Show directly connected networks"
|
||||
command_help "rules" "Show active rules"
|
||||
command_help "status" "Show all status"
|
||||
command_help "internal <ipv4|ipv6>" "Show internal configuration <default: ipv4>"
|
||||
command_help "use <iface> <cmd>" "Run a command bound to <iface> and avoid mwan3 rules"
|
||||
}
|
||||
|
||||
ifdown() {
|
||||
ifdown()
|
||||
{
|
||||
if [ -z "$1" ]; then
|
||||
echo "Error: Expecting interface. Usage: mwan3 ifdown <interface>"
|
||||
exit 0
|
||||
echo "Error: Expecting interface. Usage: mwan3 ifdown <interface>" && exit 0
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
echo "Error: Too many arguments. Usage: mwan3 ifdown <interface>"
|
||||
exit 0
|
||||
echo "Error: Too many arguments. Usage: mwan3 ifdown <interface>" && exit 0
|
||||
fi
|
||||
|
||||
mwan3_interface_hotplug_shutdown "$1" 1
|
||||
ACTION=ifdown INTERFACE=$1 /sbin/hotplug-call iface
|
||||
|
||||
kill $(pgrep -f "mwan3track $1 $2") &> /dev/null
|
||||
mwan3_track_clean $1
|
||||
}
|
||||
|
||||
ifup() {
|
||||
. /etc/init.d/mwan3
|
||||
ifup()
|
||||
{
|
||||
local device enabled up l3_device status
|
||||
|
||||
config_load mwan3
|
||||
config_get_bool enabled globals 'enabled' 0
|
||||
[ ${enabled} -gt 0 ] || {
|
||||
echo "The service mwan3 is global disabled."
|
||||
echo "Please execute \"/etc/init.d/mwan3 start\" first."
|
||||
exit 1
|
||||
}
|
||||
|
||||
if [ -z "$1" ]; then
|
||||
echo "Expecting interface. Usage: mwan3 ifup <interface>"
|
||||
exit 0
|
||||
echo "Expecting interface. Usage: mwan3 ifup <interface>" && exit 0
|
||||
fi
|
||||
|
||||
if [ -n "$2" ]; then
|
||||
echo "Too many arguments. Usage: mwan3 ifup <interface>"
|
||||
exit 0
|
||||
echo "Too many arguments. Usage: mwan3 ifup <interface>" && exit 0
|
||||
fi
|
||||
|
||||
mwan3_ifup "$1" "cmd"
|
||||
status=$(ubus -S call network.interface.$1 status)
|
||||
[ -n "$status" ] && {
|
||||
json_load "$status"
|
||||
json_get_vars up l3_device
|
||||
}
|
||||
|
||||
config_get enabled "$1" enabled 0
|
||||
|
||||
if [ "$up" = "1" ] \
|
||||
&& [ -n "$l3_device" ] \
|
||||
&& [ "$enabled" = "1" ]; then
|
||||
ACTION=ifup INTERFACE=$1 DEVICE=$l3_device /sbin/hotplug-call iface
|
||||
fi
|
||||
}
|
||||
|
||||
interfaces()
|
||||
@ -69,40 +82,37 @@ interfaces()
|
||||
|
||||
echo "Interface status:"
|
||||
config_foreach mwan3_report_iface_status interface
|
||||
echo
|
||||
echo -e
|
||||
}
|
||||
|
||||
policies()
|
||||
{
|
||||
echo "Current ipv4 policies:"
|
||||
mwan3_report_policies_v4
|
||||
echo
|
||||
[ $NO_IPV6 -ne 0 ] && return
|
||||
echo -e
|
||||
echo "Current ipv6 policies:"
|
||||
mwan3_report_policies_v6
|
||||
echo
|
||||
echo -e
|
||||
}
|
||||
|
||||
connected()
|
||||
{
|
||||
echo "Directly connected ipv4 networks:"
|
||||
mwan3_report_connected_v4
|
||||
echo
|
||||
[ $NO_IPV6 -ne 0 ] && return
|
||||
echo -e
|
||||
echo "Directly connected ipv6 networks:"
|
||||
mwan3_report_connected_v6
|
||||
echo
|
||||
echo -e
|
||||
}
|
||||
|
||||
rules()
|
||||
{
|
||||
echo "Active ipv4 user rules:"
|
||||
mwan3_report_rules_v4
|
||||
echo
|
||||
[ $NO_IPV6 -ne 0 ] && return
|
||||
echo -e
|
||||
echo "Active ipv6 user rules:"
|
||||
mwan3_report_rules_v6
|
||||
echo
|
||||
echo -e
|
||||
}
|
||||
|
||||
status()
|
||||
@ -113,136 +123,86 @@ status()
|
||||
rules
|
||||
}
|
||||
|
||||
internal()
|
||||
start()
|
||||
{
|
||||
local family="$1"
|
||||
local dash="-------------------------------------------------"
|
||||
local enabled
|
||||
|
||||
if [ -f "/etc/openwrt_release" ]; then
|
||||
. /etc/openwrt_release
|
||||
fi
|
||||
uci_toggle_state mwan3 globals enabled "1"
|
||||
|
||||
local ipt ip output
|
||||
config_load mwan3
|
||||
config_foreach ifup interface
|
||||
}
|
||||
|
||||
if [ "$family" = "ipv6" ]; then
|
||||
ipt="$IPT6"
|
||||
ip="$IP6"
|
||||
else
|
||||
ipt="$IPT4"
|
||||
ip="$IP4"
|
||||
fi
|
||||
stop()
|
||||
{
|
||||
local ipset route rule table IP IPT pid
|
||||
|
||||
echo "Software-Version"
|
||||
echo "$dash"
|
||||
mwan3_lock "command" "mwan3"
|
||||
|
||||
if [ "$DISTRIB_RELEASE" != "" ]; then
|
||||
echo "OpenWrt - $DISTRIB_RELEASE"
|
||||
else
|
||||
echo "OpenWrt - unknown"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Output of \"$ip a show\""
|
||||
echo "$dash"
|
||||
output="$($ip a show)"
|
||||
if [ "$output" != "" ]; then
|
||||
echo "$output"
|
||||
else
|
||||
echo "No data found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Output of \"$ip route show\""
|
||||
echo "$dash"
|
||||
output="$($ip route show)"
|
||||
if [ "$output" != "" ]; then
|
||||
echo "$output"
|
||||
else
|
||||
echo "No data found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Output of \"$ip rule show\""
|
||||
echo "$dash"
|
||||
output="$($ip rule show)"
|
||||
if [ "$output" != "" ]; then
|
||||
echo "$output"
|
||||
else
|
||||
echo "No data found"
|
||||
fi
|
||||
|
||||
echo ""
|
||||
echo "Output of \"$ip route list table 1-250\""
|
||||
echo "$dash"
|
||||
local dump=0
|
||||
for i in $(seq 1 250); do
|
||||
output=$($ip route list table $i 2>/dev/null)
|
||||
if [ "$output" != "" ];then
|
||||
dump=1
|
||||
echo "Routing table $i:"
|
||||
echo "$output"
|
||||
echo ""
|
||||
fi
|
||||
for pid in $(pgrep -f "mwan3rtmon"); do
|
||||
kill -TERM "$pid" > /dev/null 2>&1
|
||||
sleep 1
|
||||
kill -KILL "$pid" > /dev/null 2>&1
|
||||
done
|
||||
if [ "$dump" = "0" ]; then
|
||||
echo "No data found"
|
||||
echo ""
|
||||
fi
|
||||
|
||||
echo "Output of \"$ipt -L -v -n\""
|
||||
echo "$dash"
|
||||
output="$($ipt -L -v -n)"
|
||||
if [ "$output" != "" ]; then
|
||||
echo "$output"
|
||||
else
|
||||
echo "No data found"
|
||||
fi
|
||||
}
|
||||
for pid in $(pgrep -f "mwan3track"); do
|
||||
kill -TERM "$pid" > /dev/null 2>&1
|
||||
sleep 1
|
||||
kill -KILL "$pid" > /dev/null 2>&1
|
||||
done
|
||||
|
||||
start() {
|
||||
/etc/init.d/mwan3 enable
|
||||
/etc/init.d/mwan3 start
|
||||
}
|
||||
config_load mwan3
|
||||
config_foreach mwan3_track_clean interface
|
||||
|
||||
stop() {
|
||||
/etc/init.d/mwan3 disable
|
||||
/etc/init.d/mwan3 stop
|
||||
for IP in "$IP4" "$IP6"; do
|
||||
|
||||
for route in $(seq 1 $MWAN3_INTERFACE_MAX); do
|
||||
$IP route flush table $route &> /dev/null
|
||||
done
|
||||
|
||||
for rule in $($IP rule list | egrep '^[1-2][0-9]{3}\:' | cut -d ':' -f 1); do
|
||||
$IP rule del pref $rule &> /dev/null
|
||||
done
|
||||
done
|
||||
|
||||
for IPT in "$IPT4" "$IPT6"; do
|
||||
|
||||
$IPT -D PREROUTING -j mwan3_hook &> /dev/null
|
||||
$IPT -D OUTPUT -j mwan3_hook &> /dev/null
|
||||
|
||||
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
||||
$IPT -F $table &> /dev/null
|
||||
done
|
||||
|
||||
for table in $($IPT -S | awk '{print $2}' | grep mwan3 | sort -u); do
|
||||
$IPT -X $table &> /dev/null
|
||||
done
|
||||
done
|
||||
|
||||
for ipset in $($IPS -n list | grep mwan3_); do
|
||||
$IPS -q destroy $ipset
|
||||
done
|
||||
|
||||
for ipset in $($IPS -n list | grep mwan3 | grep -E '_v4|_v6'); do
|
||||
$IPS -q destroy $ipset
|
||||
done
|
||||
|
||||
mwan3_unlock "command" "mwan3"
|
||||
|
||||
mwan3_lock_clean
|
||||
rm -rf $MWAN3_STATUS_DIR $MWAN3TRACK_STATUS_DIR
|
||||
|
||||
uci_toggle_state mwan3 globals enabled "0"
|
||||
}
|
||||
|
||||
restart() {
|
||||
/etc/init.d/mwan3 enable
|
||||
/etc/init.d/mwan3 stop
|
||||
/etc/init.d/mwan3 start
|
||||
}
|
||||
|
||||
use() {
|
||||
# Run a command with the device, src_ip and fwmark set to avoid processing by mwan3
|
||||
# firewall rules
|
||||
|
||||
local interface device src_ip family
|
||||
mwan3_init
|
||||
|
||||
interface=$1 ; shift
|
||||
[ -z "$*" ] && echo "no command specified for mwan3 use" && return
|
||||
network_get_device device $interface
|
||||
[ -z "$device" ] && echo "could not find device for $interface" && return
|
||||
|
||||
mwan3_get_src_ip src_ip $interface
|
||||
[ -z "$src_ip" ] && echo "could not find src_ip for $interface" && return
|
||||
|
||||
config_get family $interface family
|
||||
[ -z "$family" ] && echo "could not find family for $interface. Using ipv4." && family='ipv4'
|
||||
|
||||
echo "Running '$*' with DEVICE=$device SRCIP=$src_ip FWMARK=$MMX_DEFAULT FAMILY=$family"
|
||||
# shellcheck disable=SC2048
|
||||
FAMILY=$family DEVICE=$device SRCIP=$src_ip FWMARK=$MMX_DEFAULT LD_PRELOAD=/lib/mwan3/libwrap_mwan3_sockopt.so.1.0 $*
|
||||
|
||||
stop
|
||||
start
|
||||
}
|
||||
|
||||
case "$1" in
|
||||
ifup|ifdown|interfaces|policies|connected|rules|status|start|stop|restart|use|internal)
|
||||
ifup|ifdown|interfaces|policies|connected|rules|status|start|stop|restart)
|
||||
mwan3_init
|
||||
# shellcheck disable=SC2048
|
||||
$*
|
||||
;;
|
||||
*)
|
||||
|
192
mwan3/files/usr/sbin/mwan3rtmon
Normal file → Executable file
192
mwan3/files/usr/sbin/mwan3rtmon
Normal file → Executable file
@ -1,172 +1,38 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/mwan3.sh
|
||||
|
||||
trap_with_arg()
|
||||
{
|
||||
func="$1" ; shift
|
||||
pid="$1" ; shift
|
||||
for sig ; do
|
||||
# shellcheck disable=SC2064
|
||||
trap "$func $sig $pid" "$sig"
|
||||
LOG="logger -t $(basename "$0")[$$] -p"
|
||||
|
||||
clean_up() {
|
||||
$LOG notice "Stopping mwan3rtmon..."
|
||||
exit 0
|
||||
}
|
||||
|
||||
rtchange() {
|
||||
$LOG info "Detect rtchange event."
|
||||
}
|
||||
|
||||
main() {
|
||||
local rtmon_interval
|
||||
trap clean_up TERM
|
||||
trap rtchange USR1
|
||||
|
||||
config_load mwan3
|
||||
config_get rtmon_interval globals rtmon_interval '5'
|
||||
|
||||
sleep 3
|
||||
while true; do
|
||||
mwan3_lock "service" "mwan3rtmon"
|
||||
mwan3_rtmon_ipv4 || mwan3_rtmon_ipv6
|
||||
ret=$?
|
||||
mwan3_unlock "service" "mwan3rtmon"
|
||||
[ "$ret" = "0" ] || break
|
||||
[ "$rtmon_interval" = "0" ] && break
|
||||
sleep "$rtmon_interval" &
|
||||
wait
|
||||
done
|
||||
}
|
||||
|
||||
func_trap()
|
||||
{
|
||||
kill -${1} ${2} 2>/dev/null
|
||||
}
|
||||
|
||||
mwan3_add_all_routes()
|
||||
{
|
||||
local tid IP IPT route_line family active_tbls tid initial_state error
|
||||
local ipv=$1
|
||||
|
||||
add_active_tbls()
|
||||
{
|
||||
let tid++
|
||||
config_get family "$1" family ipv4
|
||||
config_get initial_state "$1" initial_state "online"
|
||||
[ "$family" != "$ipv" ] && return
|
||||
if $IPT -S "mwan3_iface_in_$1" &> /dev/null; then
|
||||
active_tbls="$active_tbls${tid} "
|
||||
fi
|
||||
}
|
||||
|
||||
add_route()
|
||||
{
|
||||
let tid++
|
||||
[ -n "${active_tbls##* $tid *}" ] && return
|
||||
error=$($IP route add table $tid $route_line 2>&1) ||
|
||||
LOG warn "failed to add $route_line to table $tid - error: $error"
|
||||
}
|
||||
|
||||
mwan3_update_dev_to_table
|
||||
[ "$ipv" = "ipv6" ] && [ $NO_IPV6 -ne 0 ] && return
|
||||
if [ "$ipv" = "ipv4" ]; then
|
||||
IP="$IP4"
|
||||
IPT="$IPT4"
|
||||
elif [ "$ipv" = "ipv6" ]; then
|
||||
IP="$IP6"
|
||||
IPT="$IPT6"
|
||||
fi
|
||||
tid=0
|
||||
active_tbls=" "
|
||||
config_foreach add_active_tbls interface
|
||||
[ "$active_tbls" = " " ] && return
|
||||
mwan3_get_routes | while read -r route_line; do
|
||||
mwan3_route_line_dev "tid" "$route_line" "$ipv"
|
||||
if [ -n "$tid" ] && [ -z "${active_tbls##* $tid *}" ]; then
|
||||
$IP route add table $tid $route_line
|
||||
elif [ -n "${route_line##default*}" ] && [ -n "${route_line##fe80::/64*}" ]; then
|
||||
config_foreach add_route interface
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
mwan3_rtmon_route_handle()
|
||||
{
|
||||
local action route_line family tbl device line tid
|
||||
|
||||
route_line=${1##"Deleted "}
|
||||
route_family=$2
|
||||
|
||||
if [ "$route_line" = "$1" ]; then
|
||||
action="replace"
|
||||
$IPS -! add mwan3_connected_${route_family} ${route_line%% *}
|
||||
else
|
||||
action="del"
|
||||
mwan3_set_connected_${route_family}
|
||||
fi
|
||||
|
||||
if [ -z "${route_line##*linkdown*}" ]; then
|
||||
LOG debug "attempting to add link on down interface - $route_line"
|
||||
fi
|
||||
|
||||
if [ "$route_family" = "ipv4" ]; then
|
||||
IP="$IP4"
|
||||
elif [ "$route_family" = "ipv6" ] && [ $NO_IPV6 -eq 0 ]; then
|
||||
IP="$IP6"
|
||||
else
|
||||
LOG warn "route update called with invalid family - $route_family"
|
||||
return
|
||||
fi
|
||||
route_line=$(echo "$route_line" | sed -ne "$MWAN3_ROUTE_LINE_EXP")
|
||||
|
||||
handle_route() {
|
||||
local error
|
||||
local iface=$1
|
||||
tbl=$($IP route list table $tid 2>/dev/null)$'\n'
|
||||
|
||||
if [ -n "$iface" ] && [ "$(mwan3_get_mwan3track_status $iface)" != "active" ]; then
|
||||
LOG debug "interface $iface is disabled - skipping '$route_line'";
|
||||
return
|
||||
fi
|
||||
|
||||
# check that action needs to be performed. May not need to take action if we
|
||||
# got a delete event, but table was already flushed
|
||||
if [ $action = "del" ] && [ -n "${tbl##*$route_line$'\n'*}" ]; then
|
||||
LOG debug "skipping already deleted route table $tid - skipping '$route_line'"
|
||||
return
|
||||
fi
|
||||
|
||||
network_get_device device "$iface"
|
||||
LOG debug "adjusting route $device: '$IP route $action table $tid $route_line'"
|
||||
error=$($IP route "$action" table $tid $route_line 2>&1)||
|
||||
LOG warn "failed: '$IP route $action table $tid $route_line' - error: $error"
|
||||
}
|
||||
handle_route_cb(){
|
||||
local iface=$1
|
||||
let tid++
|
||||
config_get family "$iface" family ipv4
|
||||
[ "$family" != "$route_family" ] && return
|
||||
handle_route "$iface"
|
||||
}
|
||||
|
||||
mwan3_update_dev_to_table
|
||||
mwan3_route_line_dev "tid" "$route_line" "$route_family"
|
||||
|
||||
if [ -n "$tid" ]; then
|
||||
handle_route
|
||||
elif [ -n "${route_line##default*}" ] && [ -n "${route_line##fe80::/64*}" ]; then
|
||||
config_foreach handle_route_cb interface
|
||||
fi
|
||||
}
|
||||
|
||||
main()
|
||||
{
|
||||
local IP family
|
||||
|
||||
mwan3_init
|
||||
|
||||
family=$1
|
||||
[ -z $family ] && family=ipv4
|
||||
if [ "$family" = "ipv6" ]; then
|
||||
if [ $NO_IPV6 -ne 0 ]; then
|
||||
LOG warn "mwan3rtmon started for ipv6, but ipv6 not enabled on system"
|
||||
exit 1
|
||||
fi
|
||||
IP="$IP6"
|
||||
else
|
||||
IP="$IP4"
|
||||
fi
|
||||
sh -c "echo \$\$; exec $IP monitor route" | {
|
||||
read -r monitor_pid
|
||||
trap_with_arg func_trap "$monitor_pid" SIGINT SIGTERM SIGKILL
|
||||
KILL -SIGSTOP $$
|
||||
while IFS='' read -r line; do
|
||||
[ -z "${line##*table*}" ] && continue
|
||||
LOG debug "handling route update $family '$line'"
|
||||
mwan3_rtmon_route_handle "$line" "$family"
|
||||
done
|
||||
} &
|
||||
child=$!
|
||||
trap_with_arg func_trap "$child" SIGINT SIGTERM SIGKILL
|
||||
mwan3_set_connected_${family}
|
||||
mwan3_add_all_routes ${family}
|
||||
kill -SIGCONT $child
|
||||
wait $child
|
||||
}
|
||||
main "$@"
|
||||
|
432
mwan3/files/usr/sbin/mwan3track
Normal file → Executable file
432
mwan3/files/usr/sbin/mwan3track
Normal file → Executable file
@ -1,348 +1,229 @@
|
||||
#!/bin/sh
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/network.sh
|
||||
. /lib/mwan3/common.sh
|
||||
|
||||
LOG="logger -t $(basename "$0")[$$] -p"
|
||||
INTERFACE=""
|
||||
DEVICE=""
|
||||
PING="/bin/ping"
|
||||
|
||||
IFDOWN_EVENT=0
|
||||
IFUP_EVENT=0
|
||||
|
||||
stop_subprocs() {
|
||||
[ -n "$SLEEP_PID" ] && kill "$SLEEP_PID" && unset SLEEP_PID
|
||||
[ -n "$TRACK_PID" ] && kill "$TRACK_PID" && unset TRACK_PID
|
||||
}
|
||||
|
||||
WRAP() {
|
||||
# shellcheck disable=SC2048
|
||||
FAMILY=$FAMILY DEVICE=$DEVICE SRCIP=$SRC_IP FWMARK=$MMX_DEFAULT LD_PRELOAD=/lib/mwan3/libwrap_mwan3_sockopt.so.1.0 $*
|
||||
}
|
||||
|
||||
clean_up() {
|
||||
LOG notice "Stopping mwan3track for interface \"${INTERFACE}\". Status was \"${STATUS}\""
|
||||
stop_subprocs
|
||||
$LOG notice "Stopping mwan3track for interface \"${INTERFACE}\""
|
||||
exit 0
|
||||
}
|
||||
|
||||
if_down() {
|
||||
LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||
$LOG info "Detect ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||
IFDOWN_EVENT=1
|
||||
stop_subprocs
|
||||
}
|
||||
|
||||
if_up() {
|
||||
LOG info "Detect ifup event on interface ${INTERFACE} (${DEVICE})"
|
||||
IFDOWN_EVENT=0
|
||||
IFUP_EVENT=1
|
||||
STARTED=1
|
||||
stop_subprocs
|
||||
}
|
||||
|
||||
ping_test_host() {
|
||||
if [ "$FAMILY" = "ipv6" ]; then
|
||||
echo "::1"
|
||||
else
|
||||
echo "127.0.0.1"
|
||||
fi
|
||||
}
|
||||
|
||||
get_ping_command() {
|
||||
if [ -x "/usr/bin/ping" ] && /usr/bin/ping -${FAMILY#ipv} -c1 -q $(ping_test_host) &>/dev/null; then
|
||||
# -4 option added in iputils c3e68ac6 so need to check if we can use it
|
||||
# or if we must use ping and ping6
|
||||
echo "/usr/bin/ping -${FAMILY#ipv}"
|
||||
elif [ "$FAMILY" = "ipv6" ] && [ -x "/usr/bin/ping6" ]; then
|
||||
echo "/usr/bin/ping6"
|
||||
elif [ "$FAMILY" = "ipv4" ] && [ -x "/usr/bin/ping" ]; then
|
||||
echo "/usr/bin/ping"
|
||||
elif [ -x "/bin/ping" ]; then
|
||||
echo "/bin/ping -${FAMILY#ipv}"
|
||||
else
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
|
||||
validate_track_method() {
|
||||
case "$1" in
|
||||
ping)
|
||||
PING=$(get_ping_command)
|
||||
if [ $? -ne 0 ]; then
|
||||
LOG warn "Missing ping. Please enable BUSYBOX_DEFAULT_PING and recompile busybox or install iputils-ping package."
|
||||
which ping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing ping. Please install iputils-ping package or enable ping util and recompile busybox."
|
||||
return 1
|
||||
fi
|
||||
}
|
||||
;;
|
||||
arping)
|
||||
command -v arping 1>/dev/null 2>&1 || {
|
||||
LOG warn "Missing arping. Please install iputils-arping package."
|
||||
which arping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing arping. Please install iputils-arping package."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
httping)
|
||||
command -v httping 1>/dev/null 2>&1 || {
|
||||
LOG warn "Missing httping. Please install httping package."
|
||||
which httping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing httping. Please install httping package."
|
||||
return 1
|
||||
}
|
||||
[ -n "$2" -a "$2" != "0.0.0.0" -a "$2" != "::" ] || {
|
||||
$LOG warn "Cannot determine source IP for the interface which is required by httping."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
nping-*)
|
||||
command -v nping 1>/dev/null 2>&1 || {
|
||||
LOG warn "Missing nping. Please install nping package."
|
||||
which nping 1>/dev/null 2>&1 || {
|
||||
$LOG warn "Missing nping. Please install nping package."
|
||||
return 1
|
||||
}
|
||||
;;
|
||||
*)
|
||||
LOG warn "Unsupported tracking method: $track_method"
|
||||
$LOG warn "Unsupported tracking method: $track_method"
|
||||
return 2
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
validate_wrap() {
|
||||
[ -x /lib/mwan3/libwrap_mwan3_sockopt.so.1.0 ] && return
|
||||
LOG error "Missing libwrap_mwan3_sockopt. Please reinstall mwan3." &&
|
||||
exit 1
|
||||
}
|
||||
|
||||
disconnected() {
|
||||
local status="$(cat ${MWAN3TRACK_STATUS_DIR}/${INTERFACE}/STATUS)"
|
||||
|
||||
STATUS='offline'
|
||||
echo "offline" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS
|
||||
get_uptime > $MWAN3TRACK_STATUS_DIR/$INTERFACE/OFFLINE
|
||||
echo "0" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/ONLINE
|
||||
score=0
|
||||
[ "$1" = 1 ] && return
|
||||
|
||||
# Only execute disconnectd action if status was online or disconnecting
|
||||
if [ "$status" = "online" ] || [ "$status" = "disconnecting" ]; then
|
||||
LOG notice "Interface $INTERFACE ($DEVICE) is offline"
|
||||
env -i ACTION="disconnected" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||
else
|
||||
LOG notice "Skip disconnected event for $INTERFACE ($DEVICE)"
|
||||
fi
|
||||
}
|
||||
|
||||
connected() {
|
||||
STATUS='online'
|
||||
echo "online" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS
|
||||
echo "0" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/OFFLINE
|
||||
get_uptime > $MWAN3TRACK_STATUS_DIR/$INTERFACE/ONLINE
|
||||
score=$((down+up))
|
||||
host_up_count=0
|
||||
lost=0
|
||||
turn=0
|
||||
loss=0
|
||||
LOG notice "Interface $INTERFACE ($DEVICE) is online"
|
||||
env -i FIRSTCONNECT=$1 ACTION="connected" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||
}
|
||||
|
||||
disconnecting() {
|
||||
if [ "$STATUS" != "disconnecting" ] ; then
|
||||
STATUS="disconnecting"
|
||||
echo "disconnecting" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS
|
||||
LOG notice "Interface $INTERFACE ($DEVICE) is disconnecting"
|
||||
env -i ACTION="disconnecting" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||
fi
|
||||
}
|
||||
|
||||
connecting() {
|
||||
if [ "$STATUS" != "connecting" ] ; then
|
||||
STATUS="connecting"
|
||||
echo "connecting" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS
|
||||
LOG notice "Interface $INTERFACE ($DEVICE) is connecting"
|
||||
env -i ACTION="connecting" INTERFACE="$INTERFACE" DEVICE="$DEVICE" /sbin/hotplug-call iface
|
||||
fi
|
||||
}
|
||||
|
||||
disabled() {
|
||||
STATUS='disabled'
|
||||
echo "disabled" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS
|
||||
STARTED=0
|
||||
}
|
||||
|
||||
firstconnect() {
|
||||
local true_iface
|
||||
network_flush_cache
|
||||
|
||||
mwan3_get_true_iface true_iface $INTERFACE
|
||||
network_get_device DEVICE $true_iface
|
||||
|
||||
if [ "$STATUS" != "online" ]; then
|
||||
config_get STATUS $INTERFACE initial_state "online"
|
||||
fi
|
||||
|
||||
if ! network_is_up $true_iface || [ -z "$DEVICE" ]; then
|
||||
disabled
|
||||
return
|
||||
fi
|
||||
|
||||
mwan3_get_src_ip SRC_IP $INTERFACE
|
||||
|
||||
LOG debug "firstconnect: called on $INTERFACE/$true_iface ($DEVICE). Status is $STATUS. SRC_IP is $SRC_IP"
|
||||
|
||||
STARTED=1
|
||||
if [ "$STATUS" = "offline" ]; then
|
||||
disconnected 1
|
||||
else
|
||||
connected 1
|
||||
fi
|
||||
}
|
||||
|
||||
update_status() {
|
||||
local track_ip=$1
|
||||
|
||||
echo "$2" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/TRACK_${track_ip}
|
||||
[ -z "$3" ] && return
|
||||
echo "$3" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/LATENCY_${track_ip}
|
||||
echo "$4" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/LOSS_${track_ip}
|
||||
}
|
||||
|
||||
main() {
|
||||
local reliability count timeout interval failure_interval
|
||||
local recovery_interval down up size
|
||||
local keep_failure_interval check_quality failure_latency
|
||||
local recovery_latency failure_loss recovery_loss
|
||||
local max_ttl httping_ssl
|
||||
|
||||
local max_ttl httping_ssl track_ips do_log
|
||||
[ -z "$5" ] && echo "Error: should not be started manually" && exit 0
|
||||
|
||||
INTERFACE=$1
|
||||
STATUS=""
|
||||
STARTED=0
|
||||
TRACK_OUTPUT=$MWAN3TRACK_STATUS_DIR/$INTERFACE/TRACK_OUTPUT
|
||||
|
||||
mwan3_init
|
||||
|
||||
mkdir -p $MWAN3TRACK_STATUS_DIR/$INTERFACE
|
||||
|
||||
DEVICE=$2
|
||||
STATUS=$3
|
||||
SRC_IP=$4
|
||||
mkdir -p /var/run/mwan3track/$1
|
||||
trap clean_up TERM
|
||||
trap if_down USR1
|
||||
trap if_up USR2
|
||||
|
||||
config_get FAMILY $INTERFACE family ipv4
|
||||
config_get track_method $INTERFACE track_method ping
|
||||
config_get_bool httping_ssl $INTERFACE httping_ssl 0
|
||||
validate_track_method $track_method || {
|
||||
config_load mwan3
|
||||
config_get track_method $1 track_method ping
|
||||
config_get_bool httping_ssl $1 httping_ssl 0
|
||||
validate_track_method $track_method $SRC_IP || {
|
||||
track_method=ping
|
||||
if validate_track_method $track_method; then
|
||||
LOG warn "Using ping to track interface $INTERFACE avaliability"
|
||||
$LOG warn "Using ping to track interface $INTERFACE avaliability"
|
||||
else
|
||||
LOG err "No track method avaliable"
|
||||
$LOG err "No track method avaliable"
|
||||
exit 1
|
||||
fi
|
||||
}
|
||||
config_get reliability $INTERFACE reliability 1
|
||||
config_get count $INTERFACE count 1
|
||||
config_get timeout $INTERFACE timeout 4
|
||||
config_get interval $INTERFACE interval 10
|
||||
config_get down $INTERFACE down 5
|
||||
config_get up $INTERFACE up 5
|
||||
config_get size $INTERFACE size 56
|
||||
config_get max_ttl $INTERFACE max_ttl 60
|
||||
config_get failure_interval $INTERFACE failure_interval $interval
|
||||
config_get_bool keep_failure_interval $INTERFACE keep_failure_interval 0
|
||||
config_get recovery_interval $INTERFACE recovery_interval $interval
|
||||
config_get_bool check_quality $INTERFACE check_quality 0
|
||||
config_get failure_latency $INTERFACE failure_latency 1000
|
||||
config_get recovery_latency $INTERFACE recovery_latency 500
|
||||
config_get failure_loss $INTERFACE failure_loss 40
|
||||
config_get recovery_loss $INTERFACE recovery_loss 10
|
||||
local sleep_time result ping_status loss latency
|
||||
mwan3_list_track_ips()
|
||||
{
|
||||
track_ips="$track_ips $1"
|
||||
}
|
||||
config_list_foreach "$1" track_ip mwan3_list_track_ips
|
||||
config_get reliability $1 reliability 1
|
||||
config_get count $1 count 1
|
||||
config_get timeout $1 timeout 4
|
||||
config_get interval $1 interval 10
|
||||
config_get down $1 down 5
|
||||
config_get up $1 up 5
|
||||
config_get size $1 size 56
|
||||
config_get max_ttl $1 max_ttl 60
|
||||
config_get failure_interval $1 failure_interval $interval
|
||||
config_get_bool keep_failure_interval $1 keep_failure_interval 0
|
||||
config_get recovery_interval $1 recovery_interval $interval
|
||||
config_get_bool check_quality $1 check_quality 0
|
||||
config_get failure_latency $1 failure_latency 1000
|
||||
config_get recovery_latency $1 recovery_latency 500
|
||||
config_get failure_loss $1 failure_loss 40
|
||||
config_get recovery_loss $1 recovery_loss 10
|
||||
|
||||
local score=$((down+up))
|
||||
local score=$(($down+$up))
|
||||
local track_ips=$(echo $* | cut -d ' ' -f 5-99)
|
||||
local host_up_count=0
|
||||
local lost=0
|
||||
local sleep_time=0
|
||||
local turn=0
|
||||
local result
|
||||
local ping_protocol=4
|
||||
local ping_result
|
||||
local ping_result_raw
|
||||
local ping_status
|
||||
local loss=0
|
||||
local latency=0
|
||||
|
||||
firstconnect
|
||||
if [ "$STATUS" = "offline" ]; then
|
||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
||||
echo "0" > /var/run/mwan3track/$1/ONLINE
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE
|
||||
score=0
|
||||
else
|
||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
||||
echo "0" > /var/run/mwan3track/$1/OFFLINE
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/ONLINE
|
||||
env -i ACTION="connected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface
|
||||
fi
|
||||
while true; do
|
||||
[ $STARTED -eq 0 ] && { sleep $MAX_SLEEP & SLEEP_PID=$!; wait; }
|
||||
unset SLEEP_PID
|
||||
|
||||
sleep_time=$interval
|
||||
|
||||
for track_ip in $track_ips; do
|
||||
if [ $host_up_count -lt $reliability ]; then
|
||||
case "$track_method" in
|
||||
ping)
|
||||
# pinging IPv6 hosts with an interface is troublesome
|
||||
# https://bugs.openwrt.org/index.php?do=details&task_id=2897
|
||||
# so get the IP address of the interface and use that instead
|
||||
if echo $track_ip | grep -q ':'; then
|
||||
ADDR=$(ip -6 addr ls dev "$DEVICE" | sed -ne '/\/128/d' -e 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p' | head -n1)
|
||||
[ -z "$ADDR" ] && ADDR=$(ip -6 addr ls dev "$DEVICE" | sed -ne 's/ *inet6 \([^ \/]*\).* scope global.*/\1/p')
|
||||
ping_protocol=6
|
||||
fi
|
||||
if [ $check_quality -eq 0 ]; then
|
||||
WRAP $PING -n -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null &
|
||||
TRACK_PID=$!
|
||||
wait $TRACK_PID
|
||||
$PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip &> /dev/null
|
||||
result=$?
|
||||
else
|
||||
WRAP $PING -n -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null > $TRACK_OUTPUT &
|
||||
TRACK_PID=$!
|
||||
wait $TRACK_PID
|
||||
ping_result_raw="$($PING -$ping_protocol -I ${ADDR:-$DEVICE} -c $count -W $timeout -s $size -t $max_ttl -q $track_ip 2>/dev/null)"
|
||||
ping_status=$?
|
||||
loss="$(sed $TRACK_OUTPUT -ne 's/.*\([0-9]\+\)% packet loss.*/\1/p')"
|
||||
ping_result=$(echo "$ping_result_raw" | tail -n2)
|
||||
loss="$(echo "$ping_result" | grep "packet loss" | cut -d "," -f3 | awk '{print $1}' | sed -e 's/%//')"
|
||||
if [ "$ping_status" -ne 0 ] || [ "$loss" -eq 100 ]; then
|
||||
latency=999999
|
||||
loss=100
|
||||
else
|
||||
latency="$(sed $TRACK_OUTPUT -ne 's%\(rtt\|round-trip\).* = [^/]*/\([0-9]\+\).*%\2%p')"
|
||||
latency="$(echo "$ping_result" | grep -E 'rtt|round-trip' | cut -d "=" -f2 | cut -d "/" -f2 | cut -d "." -f1)"
|
||||
fi
|
||||
fi
|
||||
;;
|
||||
arping)
|
||||
WRAP arping -I $DEVICE -c $count -w $timeout -q $track_ip &> /dev/null &
|
||||
TRACK_PID=$!
|
||||
wait $TRACK_PID
|
||||
arping -I $DEVICE -c $count -w $timeout -q $track_ip &> /dev/null
|
||||
result=$?
|
||||
;;
|
||||
httping)
|
||||
if [ "$httping_ssl" -eq 1 ]; then
|
||||
WRAP httping -c $count -t $timeout -q "https://$track_ip" &> /dev/null &
|
||||
httping -y $SRC_IP -c $count -t $timeout -q "https://$track_ip" &> /dev/null
|
||||
else
|
||||
WRAP httping -c $count -t $timeout -q "http://$track_ip" &> /dev/null &
|
||||
httping -y $SRC_IP -c $count -t $timeout -q "http://$track_ip" &> /dev/null
|
||||
fi
|
||||
TRACK_PID=$!
|
||||
wait $TRACK_PID
|
||||
result=$?
|
||||
;;
|
||||
nping-*)
|
||||
WRAP nping -c $count $track_ip --${FAMILY#nping-} > $TRACK_OUTPUT &
|
||||
TRACK_PID=$!
|
||||
wait $TRACK_PID
|
||||
result=$(grep $TRACK_OUTPUT Lost | awk '{print $12}')
|
||||
nping-tcp)
|
||||
result=$(nping -e $DEVICE -c $count $track_ip --tcp | grep Lost | awk '{print $12}')
|
||||
;;
|
||||
nping-udp)
|
||||
result=$(nping -e $DEVICE -c $count $track_ip --udp | grep Lost | awk '{print $12}')
|
||||
;;
|
||||
nping-icmp)
|
||||
result=$(nping -e $DEVICE -c $count $track_ip --icmp | grep Lost | awk '{print $12}')
|
||||
;;
|
||||
nping-arp)
|
||||
result=$(nping -e $DEVICE -c $count $track_ip --arp | grep Lost | awk '{print $12}')
|
||||
;;
|
||||
esac
|
||||
do_log=""
|
||||
if [ $check_quality -eq 0 ]; then
|
||||
if [ $result -eq 0 ]; then
|
||||
let host_up_count++
|
||||
update_status "$track_ip" "up"
|
||||
|
||||
[ $score -le $up ] && do_log="success"
|
||||
echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
if [ $score -le $up ]; then
|
||||
$LOG info "Check ($track_method) success for target \"$track_ip\" on interface $1 ($2)"
|
||||
fi
|
||||
else
|
||||
let lost++
|
||||
update_status "$track_ip" "down"
|
||||
|
||||
[ $score -gt $up ] && do_log="failed"
|
||||
echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
if [ $score -gt $up ]; then
|
||||
$LOG info "Check ($track_method) failed for target \"$track_ip\" on interface $1 ($2)"
|
||||
fi
|
||||
fi
|
||||
[ -n "$do_log" ] && LOG info "Check ($track_method) ${do_log} for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
|
||||
else
|
||||
if [ "$loss" -ge "$failure_loss" ] || [ "$latency" -ge "$failure_latency" ]; then
|
||||
if [ "$loss" -ge "$failure_loss" -o "$latency" -ge "$failure_latency" ]; then
|
||||
let lost++
|
||||
update_status "$track_ip" "down" $latency $loss
|
||||
echo "down" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip}
|
||||
echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip}
|
||||
|
||||
[ $score -gt $up ] && do_log="failed"
|
||||
elif [ "$loss" -le "$recovery_loss" ] && [ "$latency" -le "$recovery_latency" ]; then
|
||||
if [ $score -gt $up ]; then
|
||||
$LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) failed for target \"$track_ip\" on interface $1 ($2)"
|
||||
fi
|
||||
elif [ "$loss" -le "$recovery_loss" -a "$latency" -le "$recovery_latency" ]; then
|
||||
let host_up_count++
|
||||
update_status "$track_ip" "up" $latency $loss
|
||||
echo "up" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
echo "$latency" > /var/run/mwan3track/$1/LATENCY_${track_ip}
|
||||
echo "$loss" > /var/run/mwan3track/$1/LOSS_${track_ip}
|
||||
|
||||
[ $score -le $up ] && do_log="success"
|
||||
if [ $score -le $up ]; then
|
||||
$LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) success for target \"$track_ip\" on interface $1 ($2)"
|
||||
fi
|
||||
else
|
||||
echo "skipped" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/TRACK_${track_ip}
|
||||
echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
fi
|
||||
[ -n "$do_log" ] && LOG info "Check (${track_method}: latency=${latency}ms loss=${loss}%) ${do_log} for target \"$track_ip\" on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
fi
|
||||
else
|
||||
echo "skipped" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/TRACK_${track_ip}
|
||||
echo "skipped" > /var/run/mwan3track/$1/TRACK_${track_ip}
|
||||
fi
|
||||
done
|
||||
|
||||
@ -351,62 +232,61 @@ main() {
|
||||
|
||||
if [ $score -lt $up ]; then
|
||||
score=0
|
||||
[ ${keep_failure_interval} -eq 1 ] && sleep_time=$failure_interval
|
||||
elif [ $score -eq $up ]; then
|
||||
disconnecting
|
||||
sleep_time=$failure_interval
|
||||
disconnected
|
||||
elif [ $score -gt $up ]; then
|
||||
disconnecting
|
||||
[ ${keep_failure_interval} -eq 1 ] && {
|
||||
sleep_time=$failure_interval
|
||||
}
|
||||
else
|
||||
sleep_time=$failure_interval
|
||||
fi
|
||||
|
||||
if [ $score -eq $up ]; then
|
||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
||||
env -i ACTION=ifdown INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
|
||||
score=0
|
||||
fi
|
||||
else
|
||||
if [ $score -lt $((down+up)) ] && [ $lost -gt 0 ]; then
|
||||
LOG info "Lost $((lost*count)) ping(s) on interface $INTERFACE ($DEVICE). Current score: $score"
|
||||
if [ $score -lt $(($down+$up)) ] && [ $lost -gt 0 ]; then
|
||||
$LOG info "Lost $(($lost*$count)) ping(s) on interface $1 ($2)"
|
||||
fi
|
||||
|
||||
let score++
|
||||
lost=0
|
||||
|
||||
if [ $score -lt $up ]; then
|
||||
connecting
|
||||
if [ $score -gt $up ]; then
|
||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
||||
score=$(($down+$up))
|
||||
elif [ $score -le $up ]; then
|
||||
sleep_time=$recovery_interval
|
||||
elif [ $score -eq $up ]; then
|
||||
connecting
|
||||
sleep_time=$recovery_interval
|
||||
connected
|
||||
elif [ $score -gt $up ]; then
|
||||
echo "online" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/STATUS
|
||||
score=$((down+up))
|
||||
fi
|
||||
|
||||
if [ $score -eq $up ]; then
|
||||
$LOG notice "Interface $1 ($2) is online"
|
||||
echo "online" > /var/run/mwan3track/$1/STATUS
|
||||
env -i ACTION=ifup INTERFACE=$1 DEVICE=$2 /sbin/hotplug-call iface
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
let turn++
|
||||
mkdir -p "$MWAN3TRACK_STATUS_DIR/${1}"
|
||||
echo "${lost}" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/LOST
|
||||
echo "${score}" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/SCORE
|
||||
echo "${turn}" > $MWAN3TRACK_STATUS_DIR/$INTERFACE/TURN
|
||||
get_uptime > $MWAN3TRACK_STATUS_DIR/$INTERFACE/TIME
|
||||
mkdir -p "/var/run/mwan3track/${1}"
|
||||
echo "${lost}" > /var/run/mwan3track/$1/LOST
|
||||
echo "${score}" > /var/run/mwan3track/$1/SCORE
|
||||
echo "${turn}" > /var/run/mwan3track/$1/TURN
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/TIME
|
||||
|
||||
host_up_count=0
|
||||
if [ "${IFDOWN_EVENT}" -eq 0 ] && [ "${IFUP_EVENT}" -eq 0 ]; then
|
||||
sleep "${sleep_time}" &
|
||||
SLEEP_PID=$!
|
||||
wait
|
||||
unset SLEEP_PID
|
||||
fi
|
||||
sleep "${sleep_time}" &
|
||||
wait
|
||||
|
||||
if [ "${IFDOWN_EVENT}" -eq 1 ]; then
|
||||
LOG debug "Register ifdown event on interface ${INTERFACE} (${DEVICE})"
|
||||
disconnected
|
||||
disabled
|
||||
echo "offline" > /var/run/mwan3track/$1/STATUS
|
||||
echo "$(get_uptime)" > /var/run/mwan3track/$1/OFFLINE
|
||||
echo "0" > /var/run/mwan3track/$1/ONLINE
|
||||
$LOG notice "Interface $1 ($2) is offline"
|
||||
env -i ACTION="disconnected" INTERFACE="$1" DEVICE="$2" /sbin/hotplug-call iface
|
||||
score=0
|
||||
IFDOWN_EVENT=0
|
||||
fi
|
||||
if [ "${IFUP_EVENT}" -eq 1 ]; then
|
||||
LOG debug "Register ifup event on interface ${INTERFACE} (${DEVICE})"
|
||||
firstconnect
|
||||
IFUP_EVENT=0
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
|
@ -1,255 +0,0 @@
|
||||
// SPDX-License-Identifier: GPL-2.0
|
||||
/*
|
||||
* Copyright (C) 2020 Aaron Goodman <aaronjg@alumni.stanford.edu>. All Rights Reserved.
|
||||
*/
|
||||
|
||||
/*
|
||||
* sockopt_wrap.c provides a shared library that intercepts syscalls to various
|
||||
* networking functions to bind the sockets a source IP address and network device
|
||||
* and to set the firewall mark on otugoing packets. Parameters are set using the
|
||||
* DEVICE, SRCIP, FWMARK environment variables.
|
||||
*
|
||||
* Additionally the FAMILY environment variable can be set to either 'ipv4' or
|
||||
* 'ipv6' to cause sockets opened with ipv6 or ipv4 to fail, respectively.
|
||||
*
|
||||
* Each environment variable is optional, and if not set, the library will not
|
||||
* enforce the particular parameter.
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
#include <dlfcn.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/ethernet.h>
|
||||
#include <linux/if_packet.h>
|
||||
#include <net/if.h>
|
||||
|
||||
static int (*next_socket)(int domain, int type, int protocol);
|
||||
static int (*next_setsockopt)(int sockfd, int level, int optname,
|
||||
const void *optval, socklen_t optlen);
|
||||
static int (*next_bind)(int sockfd, const struct sockaddr *addr, socklen_t addrlen);
|
||||
static int (*next_close)(int fd);
|
||||
static ssize_t (*next_send)(int sockfd, const void *buf, size_t len, int flags);
|
||||
static ssize_t (*next_sendto)(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen);
|
||||
static ssize_t (*next_sendmsg)(int sockfd, const struct msghdr *msg, int flags);
|
||||
static int (*next_connect)(int sockfd, const struct sockaddr *addr,
|
||||
socklen_t addrlen);
|
||||
static int device=0;
|
||||
static struct sockaddr_in source4 = {0};
|
||||
#ifdef CONFIG_IPV6
|
||||
static struct sockaddr_in6 source6 = {0};
|
||||
#endif
|
||||
static struct sockaddr * source = 0;
|
||||
static int sockaddr_size = 0;
|
||||
static int is_bound [1024] = {0};
|
||||
|
||||
#define next_func(x)\
|
||||
void set_next_##x(){\
|
||||
if (next_##x) return;\
|
||||
next_##x = dlsym(RTLD_NEXT, #x);\
|
||||
dlerror_handle();\
|
||||
return;\
|
||||
}
|
||||
|
||||
void dlerror_handle()
|
||||
{
|
||||
char *msg;
|
||||
if ((msg = dlerror()) != NULL) {
|
||||
fprintf(stderr, "socket: dlopen failed : %s\n", msg);
|
||||
fflush(stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
next_func(bind);
|
||||
next_func(close);
|
||||
next_func(setsockopt);
|
||||
next_func(socket);
|
||||
next_func(send);
|
||||
next_func(sendto);
|
||||
next_func(sendmsg);
|
||||
next_func(connect);
|
||||
|
||||
void dobind(int sockfd)
|
||||
{
|
||||
if (source && sockfd < 1024 && !is_bound[sockfd]) {
|
||||
set_next_bind();
|
||||
if (next_bind(sockfd, source, sockaddr_size)) {
|
||||
perror("failed to bind to ip address");
|
||||
next_close(sockfd);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
is_bound[sockfd] = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int connect(int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
set_next_connect();
|
||||
dobind(sockfd);
|
||||
return next_connect(sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
ssize_t send(int sockfd, const void *buf, size_t len, int flags)
|
||||
{
|
||||
set_next_send();
|
||||
dobind(sockfd);
|
||||
return next_send(sockfd, buf, len, flags);
|
||||
}
|
||||
|
||||
ssize_t sendto(int sockfd, const void *buf, size_t len, int flags,
|
||||
const struct sockaddr *dest_addr, socklen_t addrlen)
|
||||
{
|
||||
set_next_sendto();
|
||||
dobind(sockfd);
|
||||
return next_sendto(sockfd, buf, len, flags, dest_addr, addrlen);
|
||||
}
|
||||
|
||||
ssize_t sendmsg(int sockfd, const struct msghdr *msg, int flags)
|
||||
{
|
||||
set_next_sendmsg();
|
||||
dobind(sockfd);
|
||||
return next_sendmsg(sockfd, msg, flags);
|
||||
}
|
||||
|
||||
int bind (int sockfd, const struct sockaddr *addr, socklen_t addrlen)
|
||||
{
|
||||
set_next_bind();
|
||||
if (device && addr->sa_family == AF_PACKET) {
|
||||
((struct sockaddr_ll*)addr)->sll_ifindex=device;
|
||||
}
|
||||
else if (source && addr->sa_family == AF_INET) {
|
||||
((struct sockaddr_in*)addr)->sin_addr = source4.sin_addr;
|
||||
}
|
||||
#ifdef CONFIG_IPV6
|
||||
else if (source && addr->sa_family == AF_INET6) {
|
||||
((struct sockaddr_in6*)addr)->sin6_addr = source6.sin6_addr;
|
||||
}
|
||||
#endif
|
||||
if (sockfd < 1024)
|
||||
is_bound[sockfd] = 1;
|
||||
return next_bind(sockfd, addr, addrlen);
|
||||
}
|
||||
|
||||
int close (int sockfd)
|
||||
{
|
||||
set_next_close();
|
||||
if (sockfd < 1024)
|
||||
is_bound[sockfd]=0;
|
||||
return next_close(sockfd);
|
||||
}
|
||||
|
||||
int setsockopt(int sockfd, int level, int optname, const void *optval, socklen_t optlen)
|
||||
{
|
||||
set_next_setsockopt();
|
||||
if (level == SOL_SOCKET && (optname == SO_MARK || optname == SO_BINDTODEVICE))
|
||||
return 0;
|
||||
return next_setsockopt(sockfd, level, optname, optval, optlen);
|
||||
}
|
||||
|
||||
int socket(int domain, int type, int protocol)
|
||||
{
|
||||
int handle;
|
||||
|
||||
const char *socket_str = getenv("DEVICE");
|
||||
const char *srcip_str = getenv("SRCIP");
|
||||
const char *fwmark_str = getenv("FWMARK");
|
||||
const char *family_str = getenv("FAMILY");
|
||||
const int iface_len = socket_str ? strnlen(socket_str, IFNAMSIZ) : 0;
|
||||
int has_family = family_str && *family_str != 0;
|
||||
int has_srcip = srcip_str && *srcip_str != 0;
|
||||
const int fwmark = fwmark_str ? (int)strtol(fwmark_str, NULL, 0) : 0;
|
||||
|
||||
set_next_close();
|
||||
set_next_socket();
|
||||
set_next_send();
|
||||
set_next_setsockopt();
|
||||
set_next_sendmsg();
|
||||
set_next_sendto();
|
||||
set_next_connect();
|
||||
if(has_family) {
|
||||
#ifdef CONFIG_IPV6
|
||||
if(domain == AF_INET && strncmp(family_str,"ipv6",4) == 0)
|
||||
return -1;
|
||||
#endif
|
||||
if(domain == AF_INET6 && strncmp(family_str,"ipv4",4) == 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (domain != AF_INET
|
||||
#ifdef CONFIG_IPV6
|
||||
&& domain != AF_INET6
|
||||
#endif
|
||||
) {
|
||||
return next_socket(domain, type, protocol);
|
||||
}
|
||||
|
||||
|
||||
if (iface_len > 0) {
|
||||
if (iface_len == IFNAMSIZ) {
|
||||
fprintf(stderr,"socket: Too long iface name\n");
|
||||
fflush(stderr);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (has_srcip) {
|
||||
int s;
|
||||
void * addr_buf;
|
||||
if (domain == AF_INET) {
|
||||
addr_buf = &source4.sin_addr;
|
||||
sockaddr_size=sizeof source4;
|
||||
memset(&source4, 0, sockaddr_size);
|
||||
source4.sin_family = domain;
|
||||
source = (struct sockaddr*)&source4;
|
||||
}
|
||||
#ifdef CONFIG_IPV6
|
||||
else {
|
||||
addr_buf = &source6.sin6_addr;
|
||||
sockaddr_size=sizeof source6;
|
||||
memset(&source6, 0, sockaddr_size);
|
||||
source6.sin6_family=domain;
|
||||
source = (struct sockaddr*)&source6;
|
||||
}
|
||||
#endif
|
||||
s = inet_pton(domain, srcip_str, addr_buf);
|
||||
if (s == 0) {
|
||||
fprintf(stderr, "socket: ip address invalid format for family %s\n",
|
||||
domain == AF_INET ? "AF_INET" : domain == AF_INET6 ?
|
||||
"AF_INET6" : "unknown");
|
||||
return -1;
|
||||
}
|
||||
if (s < 0) {
|
||||
perror("inet_pton");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
handle = next_socket(domain, type, protocol);
|
||||
if (handle == -1 ) {
|
||||
return handle;
|
||||
}
|
||||
|
||||
if (iface_len > 0) {
|
||||
device=if_nametoindex(socket_str);
|
||||
if (next_setsockopt(handle, SOL_SOCKET, SO_BINDTODEVICE,
|
||||
socket_str, iface_len + 1)) {
|
||||
perror("socket: setting interface name failed with error");
|
||||
next_close(handle);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
if (fwmark > 0) {
|
||||
if (next_setsockopt(handle, SOL_SOCKET, SO_MARK,
|
||||
&fwmark, sizeof fwmark)) {
|
||||
perror("failed setting mark for socket");
|
||||
next_close(handle);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
return handle;
|
||||
}
|
Loading…
Reference in New Issue
Block a user