#!/bin/sh /etc/rc.common START=70 EXTRA_COMMANDS=clear_leases SPLASH_INTERFACES="" LIMIT_DOWN=0 LIMIT_DOWN_BURST=0 LIMIT_UP=0 silent() { "$@" 2>/dev/null } iface_add() { local cfg="$1" config_get zone "$cfg" zone [ -n "$zone" ] || return 0 config_get net "$cfg" network [ -n "$net" ] || return 0 config_get ifname "$net" ifname [ -n "$ifname" ] || return 0 config_get ipaddr "$net" ipaddr [ -n "$ipaddr" ] || return 0 config_get netmask "$net" netmask [ -n "$netmask" ] || return 0 config_get parentiface "$net" interface [ -n "$parentiface" ] && { config_get parentproto "$parentiface" proto config_get parentipaddr "$parentiface" ipaddr config_get parentnetmask "$parentiface" netmask } eval "$(ipcalc.sh $ipaddr $netmask)" iptables -t nat -A prerouting_${zone} -j luci_splash_prerouting iptables -t nat -A luci_splash_prerouting -j luci_splash_portal iptables -t filter -I luci_splash_filter -s "$NETWORK/$PREFIX" -d "$ipaddr/${netmask:-32}" -j RETURN iptables -t nat -I luci_splash_leases -s "$NETWORK/$PREFIX" -d "$ipaddr/${netmask:-32}" -j RETURN [ "$parentproto" = "static" -a -n "$parentipaddr" ] && { iptables -t filter -I luci_splash_filter -s "$NETWORK/$PREFIX" -d "$parentipaddr/${parentnetmask:-32}" -j RETURN iptables -t nat -I luci_splash_leases -s "$NETWORK/$PREFIX" -d "$parentipaddr/${parentnetmask:-32}" -j RETURN } iptables -t filter -A luci_splash_filter -s "$NETWORK/$PREFIX" -p udp --dport 53 -j RETURN iptables -t filter -A luci_splash_filter -s "$NETWORK/$PREFIX" -p tcp --dport 22 -j RETURN # XXX: ssh really needed? iptables -t filter -A luci_splash_filter -s "$NETWORK/$PREFIX" -p tcp --dport 80 -j RETURN iptables -t filter -A luci_splash_filter -s "$NETWORK/$PREFIX" -j REJECT --reject-with icmp-admin-prohibited qos_iface_add "$ifname" append SPLASH_INTERFACES "$ifname" } iface_del() { config_get zone "$1" zone [ -n "$zone" ] || return 0 while iptables -t nat -D prerouting_${zone} -j luci_splash_prerouting 2>&-; do :; done config_get net "$1" network [ -n "$net" ] || return 0 config_get ifname "$net" ifname [ -n "$ifname" ] || return 0 qos_iface_del "$ifname" } blacklist_add() { local cfg="$1" config_get mac "$cfg" mac [ -n "$mac" ] && { iptables -t filter -I luci_splash_filter -m mac --mac-source "$mac" -j DROP iptables -t nat -I luci_splash_leases -m mac --mac-source "$mac" -j DROP } } whitelist_add() { local cfg="$1" config_get mac "$cfg" mac [ -n "$mac" ] && { iptables -t filter -I luci_splash_filter -m mac --mac-source "$mac" -j RETURN iptables -t nat -I luci_splash_leases -m mac --mac-source "$mac" -j RETURN } } lease_add() { local cfg="$1" config_get mac "$cfg" mac config_get ban "$cfg" kicked ban=${ban:+DROP} [ -n "$mac" ] && { local oIFS="$IFS"; IFS=":" set -- $mac IFS="$oIFS"; unset oIFS local mac_pre="$1$2" local mac_post="$3$4$5$6" local handle="$6" iptables -t filter -I luci_splash_filter -m mac --mac-source "$mac" -j RETURN iptables -t nat -I luci_splash_leases -m mac --mac-source "$mac" -j "${ban:-RETURN}" [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ] && { iptables -t mangle -I luci_splash_mark -m mac --mac-source "$mac" -j MARK --set-mark 79 for i in $SPLASH_INTERFACES; do tc filter add dev $i parent 77:0 protocol ip prio 2 handle ::$handle u32 \ match u16 0x0800 0xFFFF at -2 match u32 0x$mac_post 0xFFFFFFFF at -12 \ match u16 0x$mac_pre 0xFFFF at -14 flowid 77:10 done } } } subnet_add() { local cfg="$1" config_get ipaddr "$cfg" ipaddr config_get netmask "$cfg" netmask [ -n "$ipaddr" ] && { iptables -t filter -I luci_splash_filter -d "$ipaddr/${netmask:-32}" -j RETURN iptables -t nat -I luci_splash_portal -d "$ipaddr/${netmask:-32}" -j RETURN } } qos_iface_add() { local iface="$1" # 77 -> download root qdisc # 78 -> upload root qdisc # 79 -> fwmark silent tc qdisc del dev "$iface" root handle 77: if [ "$LIMIT_UP" -gt 0 -a "$LIMIT_DOWN" -gt 0 ]; then tc qdisc add dev "$iface" root handle 77: htb # assume maximum rate of 20.000 kilobit for wlan tc class add dev "$iface" parent 77: classid 77:1 htb rate 20000kbit # set download limit and burst tc class add dev "$iface" parent 77:1 classid 77:10 htb \ rate ${LIMIT_DOWN}kb ceil ${LIMIT_DOWN_BURST}kb prio 2 tc qdisc add dev "$iface" parent 77:10 handle 78: sfq perturb 10 # adding ingress can result in "File exists" if qos-scripts are active silent tc qdisc add dev "$iface" ingress # set client upload speed tc filter add dev "$iface" parent ffff: protocol ip prio 1 \ handle 79 fw police rate ${LIMIT_UP}kb mtu 6k burst 6k drop fi } qos_iface_del() { local iface="$1" silent tc qdisc del dev "$iface" root handle 77: silent tc qdisc del dev "$iface" root handle 78: silent tc filter del dev "$iface" parent ffff: protocol ip prio 1 handle 79 fw } boot() { ### Setup splash-relay uci get lucid.splashr || { uci batch <> /etc/crontabs/root } } stop() { ### Clear interface rules include /lib/network scan_interfaces config_load luci_splash config_foreach iface_del iface silent iptables -t filter -D INPUT -j luci_splash_filter silent iptables -t filter -D FORWARD -j luci_splash_filter silent iptables -t mangle -D PREROUTING -j luci_splash_mark ### Clear subchains silent iptables -t nat -F luci_splash_leases silent iptables -t nat -F luci_splash_portal silent iptables -t nat -F luci_splash_prerouting silent iptables -t filter -F luci_splash_filter silent iptables -t mangle -F luci_splash_mark ### Delete subchains silent iptables -t nat -X luci_splash_leases silent iptables -t nat -X luci_splash_portal silent iptables -t nat -X luci_splash_prerouting silent iptables -t filter -X luci_splash_filter silent iptables -t mangle -X luci_splash_mark sed -ie '/\/usr\/sbin\/luci-splash sync/d' /var/spool/cron/crontabs/root } clear_leases() { stop while uci -P /var/state del luci_splash.@lease[0] 2>&-;do :; done start }