From 90544c4c56e8657d9500631f035be65cc01b653c Mon Sep 17 00:00:00 2001 From: ShanStone <31815718+ShanStone@users.noreply.github.com> Date: Tue, 16 Feb 2021 14:33:44 +0800 Subject: [PATCH 1/8] luci-app-passwall: sync with upstream source Co-authored-by: xiaorouji <60100640+xiaorouji@users.noreply.github.com> Signed-off-by: CN_SZTL --- .../model/cbi/passwall/client/global.lua | 1 + .../root/usr/share/passwall/app.sh | 90 ++++++++++++++----- .../root/usr/share/passwall/iptables.sh | 14 +-- .../root/usr/share/passwall/monitor.sh | 2 +- .../root/usr/share/passwall/rule_update.lua | 1 + 5 files changed, 77 insertions(+), 31 deletions(-) diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua index 3e7b721cbf..2cfab4bd10 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/global.lua @@ -198,6 +198,7 @@ o:depends("up_china_dns", "xray_doh") o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode")) o.rmempty = false o:reset_values() +o:value("fake_ip", translatef("Fake IP")) if api.is_finded("pdnsd") then o:value("pdnsd", "pdnsd " .. translatef("Requery DNS By %s", translate("TCP Node"))) end diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh b/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh index 607a584b19..9cfca3ff48 100755 --- a/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh +++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/app.sh @@ -211,6 +211,26 @@ gen_dnsmasq_items() { ' } +gen_dnsmasq_fake_items() { + local fwd_dns="1.2.3.4" + local outf=${1}; shift 1 + + awk -v fwd_dns="${fwd_dns}" -v outf="${outf}" ' + BEGIN { + if(outf == "") outf="/dev/stdout"; + split(fwd_dns, dns, ","); setdns=length(dns)>0; + if(setdns) for(i in dns) if(length(dns[i])==0) delete dns[i]; + fail=1; + } + ! /^$/&&!/^#/ { + fail=0 + if(! setdns) {printf("address=%s\n", $0) >>outf; next;} + if(setdns) for(i in dns) printf("address=/.%s/%s\n", $0, dns[i]) >>outf; + } + END {fflush(outf); close(outf); exit(fail);} + ' +} + check_port_exists() { port=$1 protocol=$2 @@ -841,14 +861,18 @@ start_dns() { TUN_DNS=${DNS_FORWARD} echolog " - 域名解析:直接使用UDP节点请求DNS($TUN_DNS)" ;; + fake_ip) + TUN_DNS="1.2.3.4" + echolog " - 域名解析:使用FakeIP方案..." + ;; custom) custom_dns=$(config_t_get global custom_dns) TUN_DNS="$(echo ${custom_dns} | sed 's/:/#/g')" - echolog " - 域名解析:直接使用UDP协议自定义DNS($TUN_DNS)解析..." + echolog " - 域名解析:使用UDP协议自定义DNS($TUN_DNS)解析..." ;; esac - [ -n "$chnlist" ] && [ "$DNS_MODE" != "custom" ] && { + [ -n "$chnlist" ] && [ "$DNS_MODE" != "custom" ] && [ "$DNS_MODE" != "fake_ip" ] && { [ -f "${RULES_PATH}/chnlist" ] && cp -a "${RULES_PATH}/chnlist" "${TMP_PATH}/chnlist" [ -n "$(first_type chinadns-ng)" ] && { echolog "发现ChinaDNS-NG,将启动。" @@ -909,31 +933,38 @@ add_dnsmasq() { #始终用国内DNS解析节点域名 fwd_dns="${LOCAL_DNS}" servers=$(uci show "${CONFIG}" | grep ".address=" | cut -d "'" -f 2) - hosts_foreach "servers" host_from_url | grep -v "google.c" | grep '[a-zA-Z]$' | sort -u | gen_dnsmasq_items "vpsiplist" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/00-vpsiplist_host.conf" + hosts_foreach "servers" host_from_url | grep -v "google.c" | grep '[a-zA-Z]$' | sort -u | gen_dnsmasq_items "vpsiplist,vpsiplist6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/00-vpsiplist_host.conf" echolog " - [$?]节点列表中的域名(vpsiplist):${fwd_dns:-默认}" #始终用国内DNS解析直连(白名单)列表 fwd_dns="${LOCAL_DNS}" [ -n "$CHINADNS_NG" ] && unset fwd_dns - sort -u "${RULES_PATH}/direct_host" | gen_dnsmasq_items "whitelist" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/01-direct_host.conf" + sort -u "${RULES_PATH}/direct_host" | gen_dnsmasq_items "whitelist,whitelist_6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/01-direct_host.conf" echolog " - [$?]域名白名单(whitelist):${fwd_dns:-默认}" #始终使用远程DNS解析代理(黑名单)列表 - fwd_dns="${TUN_DNS}" - [ -n "$CHINADNS_NG" ] && fwd_dns="${china_ng_gfw}" - [ -n "$CHINADNS_NG" ] && unset fwd_dns - sort -u "${RULES_PATH}/proxy_host" | gen_dnsmasq_items "blacklist" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/99-proxy_host.conf" - echolog " - [$?]代理域名表(blacklist):${fwd_dns:-默认}" + if [ "${DNS_MODE}" = "fake_ip" ]; then + sort -u "${RULES_PATH}/proxy_host" | gen_dnsmasq_fake_items "${TMP_DNSMASQ_PATH}/99-proxy_host.conf" + else + fwd_dns="${TUN_DNS}" + [ -n "$CHINADNS_NG" ] && fwd_dns="${china_ng_gfw}" + [ -n "$CHINADNS_NG" ] && unset fwd_dns + sort -u "${RULES_PATH}/proxy_host" | gen_dnsmasq_items "blacklist,blacklist_6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/99-proxy_host.conf" + echolog " - [$?]代理域名表(blacklist):${fwd_dns:-默认}" + fi #如果开启了通过代理订阅 [ "$(config_t_get global_subscribe subscribe_proxy 0)" = "1" ] && { fwd_dns="${TUN_DNS}" [ -n "$CHINADNS_NG" ] && fwd_dns="${china_ng_gfw}" - items=$(get_enabled_anonymous_secs "@subscribe_list") - for item in ${items}; do - host_from_url "$(config_n_get ${item} url)" | gen_dnsmasq_items "blacklist" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/99-subscribe.conf" + for item in $(get_enabled_anonymous_secs "@subscribe_list"); do + if [ "${DNS_MODE}" = "fake_ip" ]; then + host_from_url "$(config_n_get ${item} url)" | gen_dnsmasq_fake_items "${TMP_DNSMASQ_PATH}/99-subscribe.conf" + else + host_from_url "$(config_n_get ${item} url)" | gen_dnsmasq_items "blacklist,blacklist_6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/99-subscribe.conf" + fi done - echolog " - [$?]节点订阅域名(blacklist):${fwd_dns:-默认}" + [ "${DNS_MODE}" != "fake_ip" ] && echolog " - [$?]节点订阅域名(blacklist):${fwd_dns:-默认}" } #分流规则 @@ -948,25 +979,36 @@ add_dnsmasq() { fi local shunt_node=$(config_n_get $shunt_node_id address nil) [ "$shunt_node" = "nil" ] && continue - config_n_get $shunt_id domain_list | grep -v 'regexp:\|geosite:\|ext:' | sed 's/domain:\|full:\|//g' | tr -s "\r\n" "\n" | sort -u | gen_dnsmasq_items "shuntlist" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/998-shunt_host.conf" + if [ "${DNS_MODE}" = "fake_ip" ]; then + config_n_get $shunt_id domain_list | grep -v 'regexp:\|geosite:\|ext:' | sed 's/domain:\|full:\|//g' | tr -s "\r\n" "\n" | sort -u | gen_dnsmasq_fake_items "${TMP_DNSMASQ_PATH}/998-shunt_host.conf" + else + config_n_get $shunt_id domain_list | grep -v 'regexp:\|geosite:\|ext:' | sed 's/domain:\|full:\|//g' | tr -s "\r\n" "\n" | sort -u | gen_dnsmasq_items "shuntlist,shuntlist6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/998-shunt_host.conf" + fi done - echolog " - [$?]Xray分流规则(shuntlist):${fwd_dns:-默认}" + [ "${DNS_MODE}" != "fake_ip" ] && echolog " - [$?]Xray分流规则(shuntlist):${fwd_dns:-默认}" } #如果没有使用回国模式 if [ -z "${returnhome}" ]; then - fwd_dns="${TUN_DNS}" - [ -n "$CHINADNS_NG" ] && fwd_dns="${china_ng_gfw}" - [ -n "$CHINADNS_NG" ] && unset fwd_dns [ ! -f "${TMP_PATH}/gfwlist.txt" ] && sed -n 's/^ipset=\/\.\?\([^/]*\).*$/\1/p' "${RULES_PATH}/gfwlist.conf" | sort -u > "${TMP_PATH}/gfwlist.txt" - #sort -u "${TMP_PATH}/gfwlist.txt" | gen_dnsmasq_items "gfwlist" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/999-gfwlist.conf" - sort -u "${TMP_PATH}/gfwlist.txt" | gen_dnsmasq_items "gfwlist,gfwlist6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/999-gfwlist.conf" - echolog " - [$?]防火墙域名表(gfwlist):${fwd_dns:-默认}" + if [ "${DNS_MODE}" = "fake_ip" ]; then + sort -u "${TMP_PATH}/gfwlist.txt" | gen_dnsmasq_fake_items "${TMP_DNSMASQ_PATH}/999-gfwlist.conf" + else + fwd_dns="${TUN_DNS}" + [ -n "$CHINADNS_NG" ] && fwd_dns="${china_ng_gfw}" + [ -n "$CHINADNS_NG" ] && unset fwd_dns + sort -u "${TMP_PATH}/gfwlist.txt" | gen_dnsmasq_items "gfwlist,gfwlist6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/999-gfwlist.conf" + echolog " - [$?]防火墙域名表(gfwlist):${fwd_dns:-默认}" + fi else #回国模式 - fwd_dns="${TUN_DNS}" - sort -u "${RULES_PATH}/chnlist" | gen_dnsmasq_items "chnroute" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/02-chinalist_host.conf" - echolog " - [$?]中国域名表(chnroute):${fwd_dns:-默认}" + if [ "${DNS_MODE}" = "fake_ip" ]; then + sort -u "${RULES_PATH}/chnlist" | gen_dnsmasq_fake_items "${TMP_DNSMASQ_PATH}/02-chinalist_host.conf" + else + fwd_dns="${TUN_DNS}" + sort -u "${RULES_PATH}/chnlist" | gen_dnsmasq_items "chnroute,chnroute6" "${fwd_dns}" "${TMP_DNSMASQ_PATH}/02-chinalist_host.conf" + echolog " - [$?]中国域名表(chnroute):${fwd_dns:-默认}" + fi fi fi diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/iptables.sh b/package/lienol/luci-app-passwall/root/usr/share/passwall/iptables.sh index b500628a8d..c14fd0826c 100755 --- a/package/lienol/luci-app-passwall/root/usr/share/passwall/iptables.sh +++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/iptables.sh @@ -476,7 +476,7 @@ add_firewall_rule() { done for shunt_id in $shunt_ids; do - config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{0,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_SHUNTLIST_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + config_n_get $shunt_id ip_list | tr -s "\r\n" "\n" | sed -e "/^$/d" | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "s/^/add $IPSET_SHUNTLIST_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R done cat $RULES_PATH/chnroute | sed -e "/^$/d" | sed -e "s/^/add $IPSET_CHN &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R @@ -486,10 +486,10 @@ add_firewall_rule() { cat $RULES_PATH/direct_ip | sed -e "/^$/d" | grep -E "(\.((2(5[0-5]|[0-4]\d))|[0-1]?\d{1,2})){3}" | sed -e "s/^/add $IPSET_WHITELIST &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R cat $RULES_PATH/chnroute6 | sed -e "/^$/d" | sed -e "s/^/add $IPSET_CHN6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - cat $RULES_PATH/proxy_ip | grep -E "([A-Fa-f0-9]{0,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_BLACKLIST_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - [ -f "$RULES_PATH/proxy_ip2" ] && cat $RULES_PATH/proxy_ip2 | grep -E "([A-Fa-f0-9]{0,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_BLACKLIST2_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - [ -f "$RULES_PATH/proxy_ip3" ] && cat $RULES_PATH/proxy_ip3 | grep -E "([A-Fa-f0-9]{0,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_BLACKLIST3_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R - cat $RULES_PATH/direct_ip | grep -E "([A-Fa-f0-9]{0,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_WHITELIST_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + cat $RULES_PATH/proxy_ip | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_BLACKLIST_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + [ -f "$RULES_PATH/proxy_ip2" ] && cat $RULES_PATH/proxy_ip2 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_BLACKLIST2_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + [ -f "$RULES_PATH/proxy_ip3" ] && cat $RULES_PATH/proxy_ip3 | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_BLACKLIST3_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R + cat $RULES_PATH/direct_ip | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | sed -e "/^$/d" | sed -e "s/^/add $IPSET_WHITELIST_6 &/g" | awk '{print $0} END{print "COMMIT"}' | ipset -! -R ipset -! -R <<-EOF $(gen_laniplist | sed -e "s/^/add $IPSET_LANIPLIST /") @@ -534,7 +534,7 @@ add_firewall_rule() { done } - local ISP_DNS6=$(cat $RESOLVFILE 2>/dev/null | grep -E "([A-Fa-f0-9]{0,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}'| sort -u ) + local ISP_DNS6=$(cat $RESOLVFILE 2>/dev/null | grep -E "([A-Fa-f0-9]{1,4}::?){1,7}[A-Fa-f0-9]{1,4}" | awk -F % '{print $1}' | awk -F " " '{print $2}'| sort -u ) [ -n "$ISP_DNS" ] && { #echolog "处理 ISP IPv6 DNS 例外..." for ispip6 in $ISP_DNS; do @@ -638,6 +638,7 @@ add_firewall_rule() { } [ "$use_tcp_node_resolve_dns" == 1 ] && hosts_foreach DNS_FORWARD _proxy_tcp_access 53 $ipt_tmp -A OUTPUT -p tcp -j PSW_OUTPUT + $ipt_tmp -I PSW_OUTPUT -p tcp -d 1.2.3.4 $blist_r [ "$TCP_NO_REDIR_PORTS" != "disable" ] && { $ipt_tmp -A PSW_OUTPUT -p tcp -m multiport --dport $TCP_NO_REDIR_PORTS -j RETURN $ip6t_m -A PSW_OUTPUT -p tcp -m multiport --dport $TCP_NO_REDIR_PORTS -j RETURN @@ -730,6 +731,7 @@ add_firewall_rule() { } [ "$use_udp_node_resolve_dns" == 1 ] && hosts_foreach DNS_FORWARD _proxy_udp_access 53 $ipt_m -A OUTPUT -p udp -j PSW_OUTPUT + $ipt_m -I PSW_OUTPUT -p udp -d 1.2.3.4 $(REDIRECT 1 MARK) [ "$UDP_NO_REDIR_PORTS" != "disable" ] && { $ipt_m -A PSW_OUTPUT -p udp -m multiport --dport $UDP_NO_REDIR_PORTS -j RETURN $ip6t_m -A PSW_OUTPUT -p udp -m multiport --dport $UDP_NO_REDIR_PORTS -j RETURN diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/monitor.sh b/package/lienol/luci-app-passwall/root/usr/share/passwall/monitor.sh index 991dc28752..d5499a9d95 100755 --- a/package/lienol/luci-app-passwall/root/usr/share/passwall/monitor.sh +++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/monitor.sh @@ -65,7 +65,7 @@ do #dns dns_mode=$(config_t_get global dns_mode) - if [ "$dns_mode" != "nonuse" ] && [ "$dns_mode" != "custom" ]; then + if [ "$dns_mode" != "nonuse" ] && [ "$dns_mode" != "custom" ] && [ "$dns_mode" != "fake_ip" ]; then icount=$(netstat -apn | grep 7913 | wc -l) if [ $icount = 0 ]; then /etc/init.d/$CONFIG restart diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/rule_update.lua b/package/lienol/luci-app-passwall/root/usr/share/passwall/rule_update.lua index 5f671bdcee..977fd0b65d 100755 --- a/package/lienol/luci-app-passwall/root/usr/share/passwall/rule_update.lua +++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/rule_update.lua @@ -195,6 +195,7 @@ local function fetch_chnlist() end else sret = 0 + log("chnlist 第"..k.."条规则:"..v.."下载失败!") end os.remove("/tmp/chnlist_dl"..k) end From 8ffe564799dbc8f11700f33e65e30bff5218c674 Mon Sep 17 00:00:00 2001 From: Mattraks <16359027+Mattraks@users.noreply.github.com> Date: Thu, 18 Feb 2021 10:41:11 +0800 Subject: [PATCH 2/8] luci-app-ssr-plus: bug fixes Signed-off-by: CN_SZTL --- package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr | 3 +-- .../root/usr/share/shadowsocksr/subscribe.lua | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr index 4100a3593a..1a7310fb70 100755 --- a/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr +++ b/package/lean/luci-app-ssr-plus/root/etc/init.d/shadowsocksr @@ -139,8 +139,7 @@ _exit() { } first_type() { - local ret=$(which "/bin/${path_name}" "${TMP_BIN_PATH}/${path_name}" "${path_name}" "$@" | head -n1) - echo ${ret:=$@} + type -t -p "/bin/${1}" -p "${TMP_BIN_PATH}/${1}" -p "${1}" "$@" | head -n1 } ln_start_bin() { diff --git a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua index 741f0aa145..cf6f6f8da6 100755 --- a/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua +++ b/package/lean/luci-app-ssr-plus/root/usr/share/shadowsocksr/subscribe.lua @@ -232,7 +232,7 @@ local function processData(szType, content) local userinfo = hostInfo[1] local password = userinfo result.alias = UrlDecode(alias) - result.type = "trojan" + result.type = luci.sys.exec('type -t -p trojan') ~= "" and "trojan" or "v2ray" result.v2ray_protocol = "trojan" result.server = host[1] -- 按照官方的建议 默认验证ssl证书 From ba32b641402eeec5edd317a76fb94ff2564ad2c2 Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Thu, 18 Feb 2021 20:05:10 +0800 Subject: [PATCH 3/8] luci-app-wrtbwmon: sync with upstream source Signed-off-by: CN_SZTL --- CONTRIBUTED.md | 4 +- package/ctcgfw/luci-app-wrtbwmon/Makefile | 24 + .../luci-app-wrtbwmon/etc/config/wrtbwmon | 5 + .../etc/hotplug.d/iface/99-wrtbwmon | 9 + .../luci-app-wrtbwmon/etc/init.d/wrtbwmon | 44 ++ .../luasrc/controller/wrtbwmon.lua | 20 + .../luasrc/model/cbi/wrtbwmon/config.lua | 48 ++ .../luasrc/model/cbi/wrtbwmon/custom.lua | 7 +- .../luasrc/view/wrtbwmon.htm | 579 ++++++++++++++++++ .../luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po | 152 +++++ .../root/etc/uci-defaults/luci-wrtbwmon | 11 + .../luci-app-wrtbwmon/usr/sbin/readDB.awk | 213 +++++++ .../luci-app-wrtbwmon/usr/sbin/wrtbwmon | 460 ++++++++++++++ .../usr/share/wrtbwmon/usage.htm1 | 34 + .../usr/share/wrtbwmon/usage.htm2 | 18 + package/lean/luci-app-wrtbwmon/Makefile | 17 - .../htdocs/luci-static/wrtbwmon.js | 562 ----------------- .../luasrc/controller/wrtbwmon.lua | 43 -- .../luasrc/model/cbi/wrtbwmon/config.lua | 18 - .../luasrc/view/wrtbwmon.htm | 46 -- .../luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po | 56 -- .../root/etc/config/wrtbwmon | 4 - .../root/etc/init.d/wrtbwmon | 22 - .../root/etc/uci-defaults/luci-wrtbwmon | 14 - .../root/etc/wrtbwmon.include | 1 - .../root/usr/sbin/readDB.awk | 157 ----- .../luci-app-wrtbwmon/root/usr/sbin/wrtbwmon | 301 --------- .../root/usr/share/wrtbwmon/usage.htm1 | 23 - .../root/usr/share/wrtbwmon/usage.htm2 | 14 - 29 files changed, 1625 insertions(+), 1281 deletions(-) create mode 100644 package/ctcgfw/luci-app-wrtbwmon/Makefile create mode 100644 package/ctcgfw/luci-app-wrtbwmon/etc/config/wrtbwmon create mode 100755 package/ctcgfw/luci-app-wrtbwmon/etc/hotplug.d/iface/99-wrtbwmon create mode 100755 package/ctcgfw/luci-app-wrtbwmon/etc/init.d/wrtbwmon create mode 100644 package/ctcgfw/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua create mode 100644 package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua rename package/{lean => ctcgfw}/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua (69%) create mode 100644 package/ctcgfw/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm create mode 100644 package/ctcgfw/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po create mode 100755 package/ctcgfw/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon create mode 100755 package/ctcgfw/luci-app-wrtbwmon/usr/sbin/readDB.awk create mode 100755 package/ctcgfw/luci-app-wrtbwmon/usr/sbin/wrtbwmon create mode 100644 package/ctcgfw/luci-app-wrtbwmon/usr/share/wrtbwmon/usage.htm1 create mode 100644 package/ctcgfw/luci-app-wrtbwmon/usr/share/wrtbwmon/usage.htm2 delete mode 100644 package/lean/luci-app-wrtbwmon/Makefile delete mode 100644 package/lean/luci-app-wrtbwmon/htdocs/luci-static/wrtbwmon.js delete mode 100644 package/lean/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua delete mode 100644 package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua delete mode 100644 package/lean/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm delete mode 100644 package/lean/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po delete mode 100644 package/lean/luci-app-wrtbwmon/root/etc/config/wrtbwmon delete mode 100755 package/lean/luci-app-wrtbwmon/root/etc/init.d/wrtbwmon delete mode 100755 package/lean/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon delete mode 100755 package/lean/luci-app-wrtbwmon/root/etc/wrtbwmon.include delete mode 100755 package/lean/luci-app-wrtbwmon/root/usr/sbin/readDB.awk delete mode 100755 package/lean/luci-app-wrtbwmon/root/usr/sbin/wrtbwmon delete mode 100644 package/lean/luci-app-wrtbwmon/root/usr/share/wrtbwmon/usage.htm1 delete mode 100644 package/lean/luci-app-wrtbwmon/root/usr/share/wrtbwmon/usage.htm2 diff --git a/CONTRIBUTED.md b/CONTRIBUTED.md index 2af7aa017f..8bd938af44 100644 --- a/CONTRIBUTED.md +++ b/CONTRIBUTED.md @@ -60,7 +60,9 @@ luci-app-beardropper source: [NateLol/natelol](https://github.com/NateLol/natelo luci-app-vssr source: [jerrykuku/luci-app-vssr](https://github.com/jerrykuku/luci-app-vssr).
luci-proto-modemmanager source: [nickberry17/luci-proto-modemmanager](https://github.com/nickberry17/luci-proto-modemmanager).
luci-theme-infinityfreedom source: [xiaoqingfengATGH/luci-theme-infinityfreedom](https://github.com/xiaoqingfengATGH/luci-theme-infinityfreedom).
-luci-proto-minieap source: [ysc3839/luci-proto-minieap](https://github.com/ysc3839/luci-proto-minieap). +luci-proto-minieap source: [ysc3839/luci-proto-minieap](https://github.com/ysc3839/luci-proto-minieap).
+wrtbwmon source: [brvphoenix/wrtbwmon](https://github.com/brvphoenix/wrtbwmon).
+luci-app-wrtbwmon source: [brvphoenix/luci-app-wrtbwmon](https://github.com/brvphoenix/luci-app-wrtbwmon). ## License ### Depend on their own License. diff --git a/package/ctcgfw/luci-app-wrtbwmon/Makefile b/package/ctcgfw/luci-app-wrtbwmon/Makefile new file mode 100644 index 0000000000..89f52c9f83 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/Makefile @@ -0,0 +1,24 @@ +# +# Copyright (C) 2021 ImmortalWrt +# (https://project-openwrt.eu.org) +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=luci-app-wrtbwmon +PKG_VERSION:=1.6.3 +PKG_RELEASE:=1 + +PKG_LICENSE:=Apache-2.0 +PKG_MAINTAINER:=Van Waholtz + +LUCI_TITLE:=A Luci module that uses wrtbwmon to track bandwidth usage +LUCI_DEPENDS:=+@BUSYBOX_CONFIG_IP +iptables +LUCI_PKGARCH:=all + +include $(TOPDIR)/feeds/luci/luci.mk + +# call BuildPackage - OpenWrt buildroot signature diff --git a/package/ctcgfw/luci-app-wrtbwmon/etc/config/wrtbwmon b/package/ctcgfw/luci-app-wrtbwmon/etc/config/wrtbwmon new file mode 100644 index 0000000000..da9470a111 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/etc/config/wrtbwmon @@ -0,0 +1,5 @@ + +config wrtbwmon 'general' + option enabled '1' + option path '/tmp/usage.db' + diff --git a/package/ctcgfw/luci-app-wrtbwmon/etc/hotplug.d/iface/99-wrtbwmon b/package/ctcgfw/luci-app-wrtbwmon/etc/hotplug.d/iface/99-wrtbwmon new file mode 100755 index 0000000000..41b49a4a20 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/etc/hotplug.d/iface/99-wrtbwmon @@ -0,0 +1,9 @@ +#!/bin/sh + +[ "$ACTION" = ifup -o "$ACTION" = ifupdate ] || exit 0 +[ "$ACTION" = ifupdate -a -z "$IFUPDATE_ADDRESSES" -a -z "$IFUPDATE_DATA" ] && exit 0 + +/etc/init.d/wrtbwmon restart + +logger -t wrtbwmon "Restart for $ACTION of $INTERFACE ($DEVICE)" + diff --git a/package/ctcgfw/luci-app-wrtbwmon/etc/init.d/wrtbwmon b/package/ctcgfw/luci-app-wrtbwmon/etc/init.d/wrtbwmon new file mode 100755 index 0000000000..1c3213ee17 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/etc/init.d/wrtbwmon @@ -0,0 +1,44 @@ +#!/bin/sh /etc/rc.common +# Copyright (C) 2019 OpenWrt.org + +START=99 +USE_PROCD=1 + +NAME=wrtbwmon +PID_FILE=/var/run/wrtbwmon.pid +args=/usr/sbin/wrtbwmon + +create_instance() { + procd_open_instance + procd_set_param command $args + procd_set_param respawn + procd_set_param user root +# procd_set_param pidfile $PID_FILE + procd_close_instance +} + +service_triggers() +{ + procd_add_reload_trigger "$NAME" +} + +start_service() { + local db enabled + config_load $NAME + + config_get db general path + [ -z "$db" ] && db="/tmp/usage.db" + append args " -46" + append args "-f $db" + append args "-p /tmp/usage.htm" + append args "-u /etc/wrtbwmon.user" + append args "-d" + + config_get enabled general enabled + [ "$enabled"0 -eq 0 ] || create_instance +} + +stop_service() { + procd_kill wrtbwmon + kill -CONT $(cat $PID_FILE) +} diff --git a/package/ctcgfw/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua b/package/ctcgfw/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua new file mode 100644 index 0000000000..20f254cae6 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua @@ -0,0 +1,20 @@ +module("luci.controller.wrtbwmon", package.seeall) + +function index() + if not nixio.fs.access("/etc/config/wrtbwmon") then + return + end + entry({"admin", "network", "usage"}, + alias("admin", "network", "usage", "details"), + _("Traffic Status"), 60) + entry({"admin", "network", "usage", "details"}, + template("wrtbwmon"), + _("Details"), 10).leaf=true + entry({"admin", "network", "usage", "config"}, + arcombine(cbi("wrtbwmon/config")), + _("Configuration"), 20).leaf=true + entry({"admin", "network", "usage", "custom"}, + form("wrtbwmon/custom"), + _("User file"), 30).leaf=true +end + diff --git a/package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua b/package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua new file mode 100644 index 0000000000..6b3555e451 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua @@ -0,0 +1,48 @@ +local lastvalue +local cursor = luci.model.uci.cursor() +local m, s, o +m = Map("wrtbwmon", translate("Usage - Configuration")) + +s = m:section(NamedSection, "general", "wrtbwmon", translate("General settings")) + +o = s:option(Flag, "enabled", translate("Enabled")) +o.rmempty= true + +o = s:option(Value, "path", translate("Database Path"), + translate("This box is used to select the Database path, " + .. "which is /tmp/usage.db by default.")) +o:value("/tmp/usage.db") +o:value("/etc/usage.db") +o.rmempty= false + +function m.on_parse(self) + lastvalue = cursor:get("wrtbwmon", "general", "path") +end + +function o.write(self,section,value) + local fpath = nixio.fs.dirname(value) .. "/" + + if not nixio.fs.access(fpath) then + if not nixio.fs.mkdirr(fpath) then + return Value.write(self, section, lastvalue) + end + end + + io.popen("/etc/init.d/wrtbwmon stop") + io.popen("mv -f " .. fileRename(lastvalue, "*") .. " ".. fpath) + Value.write(self,section,value) + io.popen("/etc/init.d/wrtbwmon start") + + return true +end + +function fileRename(fileName, tag) + local idx = fileName:match(".+()%.%w+$") + if(idx) then + return fileName:sub(1, idx-1) .. tag .. fileName:sub(idx, -1) + else + return fileName .. tag + end +end + +return m diff --git a/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua b/package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua similarity index 69% rename from package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua rename to package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua index 671879b4cc..46baa33127 100644 --- a/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua +++ b/package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua @@ -1,10 +1,11 @@ -local USER_FILE_PATH = "/etc/config/wrtbwmon.user" +local USER_FILE_PATH = "/etc/wrtbwmon.user" local fs = require "nixio.fs" local f = SimpleForm("wrtbwmon", translate("Usage - Custom User File"), - translate("This file is used to match users with MAC addresses and it must have the following format: 00:aa:bb:cc:ee:ff,username")) + translate("This file is used to match users with MAC addresses. " + .. "Each line must have the following format: \"00:aa:bb:cc:ee:ff,username\".")) local o = f:field(Value, "_custom") @@ -20,4 +21,6 @@ function o.write(self, section, value) fs.writefile(USER_FILE_PATH, value) end +f.submit = translate("Submit") + return f diff --git a/package/ctcgfw/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm b/package/ctcgfw/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm new file mode 100644 index 0000000000..b78e0e86fc --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm @@ -0,0 +1,579 @@ +<%# + Licensed to the public under the Apache License 2.0. +-%> + +<% + local fs = require "nixio.fs" + local stat = require "luci.tools.status" + local dba = luci.model.uci.cursor():get("wrtbwmon", "general", "path") + +-- Function to generate table from string. + local function strToTable(str) + local tb = {} + local cmd = nil + setmetatable(tb, {__index = table.insert}) + str:gsub("[^%s,]+", tb) + tb.__index = nil + return tb + end + +-- Function to update the mac-hostname table. + local function getmactable(family) + local mactable = {} + local leases = (family == 4 and {stat.dhcp_leases()} or {stat.dhcp6_leases()})[1] + + if fs.access("/etc/wrtbwmon.user") then + for line in io.lines("/etc/wrtbwmon.user") do + local macpair = strToTable(line) + mactable[macpair[1]:lower()] = macpair[2] + end + end + + for _, line in pairs(leases) do + if line.macaddr and not mactable[line.macaddr:lower()] then + mactable[line.macaddr:lower()] = line.hostname + end + end + + return mactable + end + +-- Rename the db file for ipv6. + local function fileRename(fn, tag) + local idx = fn:match(".+()%.%w+$") + if(idx) then + return fn:sub(1, idx-1) .. tag .. fn:sub(idx, -1) + else + return fn .. tag + end + end + + local function procressData(db, family) + local dbc = (family == 6 and {fileRename(db, ".6")} or {db})[1] + local cmd_setup = "/etc/init.d/wrtbwmon restart" + local cmd_update = "wrtbwmon -" .. family .. " -f " .. db .. " >>/dev/null 2>&1" + local data, total, mactable, firstline = {}, {0.0, 0.0, 0.0, 0.0, 0.0}, getmactable(family), true + local isshow = luci.http.formvalue("isShow") + +-- Setup the background update process. + if not fs.access("/var/run/wrtbwmon.pid") then + io.popen(cmd_setup) + else + io.popen(cmd_update) + end + +-- Process the database. + for line in io.lines(dbc) do + if firstline then + firstline = false + else + local tbl = strToTable(line) + if isshow == "1" or tbl[8] ~= "0" then + tbl[1] = tbl[1]:lower() + + if mactable[tbl[1]] then + tbl[3] = mactable[tbl[1]] + else + tbl[3] = tbl[1] + end + + for i = 1,#total do + total[i] = total[i] + (tbl[i+3] .. ".0") + end + + data[#data+1] = {tbl[3], tbl[1], unpack(tbl, 4)} + table.insert(data[#data], tbl[2]) + end + end + end + +-- Transfer the database to js. + luci.http.prepare_content("application/json") + luci.http.write_json({data, total}) + return + end + + if luci.http.formvalue("proto") == "ipv4" then + procressData(dba, 4) + return + elseif luci.http.formvalue("proto") == "ipv6" then + procressData(dba, 6) + return + end + + if luci.http.formvalue("reset") == "1" then + os.execute("ip -4 neigh flush dev br-lan && ip -6 neigh flush dev br-lan") + os.execute("rm -f " .. fileRename(dba, "*") .. " && wrtbwmon -46 -f " .. dba .. " >>/dev/null 2>&1") + luci.http.status(200, "OK") + return + end +-%> + +<%+header%> + + + +
+

<%:Usage - Details%>

+ +
+
+
+
+
+ +
+
+
+ +
+
+ +
+
+
+
+
+ +
+
+ +
+
+ +
+
+
+
+
+ +
+
+
+
+
+
+
+ + +
+
+
+ +
+
<%:downflow:%>
+
<%:upflow:%>
+
+ +
+
+
<%:Clients%>
+
<%:MAC%>
+
<%:Download%>
+
<%:Upload%>
+
<%:Total Down%>
+
<%:Total Up%>
+
<%:Total%>
+
<%:First Seen%>
+
<%:Last Seen%>
+
+
+
<%:Collecting data...%>
+
+
+
+
+ + + + +<%+footer%> diff --git a/package/ctcgfw/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po b/package/ctcgfw/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po new file mode 100644 index 0000000000..02033745c8 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po @@ -0,0 +1,152 @@ +msgid "Traffic Status" +msgstr "流量监控" + +msgid "Usage - Configuration" +msgstr "文件设置" + +msgid "Details" +msgstr "流量信息" + +msgid "Configuration" +msgstr "设置" + +msgid "User file" +msgstr "用户文件" + +msgid "General settings" +msgstr "通用设置" + +msgid "Wrtbwmon is a mointor of the traffic usage." +msgstr "Wrtbwmon是一个流量监控器" + +msgid "This box is used to select the Database path, which is /tmp/usage.db by default." +msgstr "该选项用于选择数据存储路径,默认路径为/tmp/usage.db。" + +msgid "This box is used to set the total bandwidth (Byte/s), which is 1000000Byte/s by default." +msgstr "该选项用于选设置总的带宽(Byte/s),默认带宽值1000000Byte/s。" + +msgid "Usage - Custom User File" +msgstr "用户文件配置" + +msgid "This file is used to match users with MAC addresses. Each line must have the following format: \"00:aa:bb:cc:ee:ff,username\"." +msgstr "该文件用来进行MAC和主机进行匹配。每行必须满足\"00:aa:bb:cc:ee:ff,用户名\"的格式" + +msgid "Usage - Details" +msgstr "流量详情" + +msgid "downflow:" +msgstr "下行:" + +msgid "upflow:" +msgstr "上行:" + +msgid "protocol:" +msgstr "协议:" + +msgid "Reset Database" +msgstr "重置" + +msgid "Auto update every" +msgstr "自动刷新" + +msgid "Database Path" +msgstr "数据存储位置" + +msgid "Show Zeros:" +msgstr "显示0流量:" + +msgid "Show More:" +msgstr "显示更多:" + +msgid "bandwidth:" +msgstr "带宽:" + +msgid "Calculate per host totals" +msgstr "单主机总流量统计" + +msgid "Disabled" +msgstr "禁用" + +msgid "1 second" +msgstr "1秒" + +msgid "2 seconds" +msgstr "2秒" + +msgid "5 seconds" +msgstr "5秒" + +msgid "10 seconds" +msgstr "10秒" + +msgid "20 seconds" +msgstr "20秒" + +msgid "30 seconds" +msgstr "30秒" + +msgid "40 seconds" +msgstr "40秒" + +msgid "50 seconds" +msgstr "50秒" + +msgid "60 seconds" +msgstr "60秒" + +msgid "2 minutes" +msgstr "2分" + +msgid "3 minutes" +msgstr "3分" + +msgid "Loading..." +msgstr "数据载入中" + +msgid "Clients" +msgstr "客户端" + +msgid "MAC Address" +msgstr "MAC地址" + +msgid "Download" +msgstr "下载" + +msgid "Upload" +msgstr "上传" + +msgid "Total Down" +msgstr "总下载" + +msgid "Total Up" +msgstr "总上传" + +msgid "Total" +msgstr "总计" + +msgid "First Seen" +msgstr "初次记录" + +msgid "Last Seen" +msgstr "最后记录" + +msgid "TOTAL" +msgstr "总共" + +msgid "Last updated" +msgstr "最后更新于" + +msgid "This will delete the database file. Are you sure?" +msgstr "该操作将删除数据统计文件,确定执行该操作?" + +msgid "Updating again in" +msgstr "下次更新将于" + +msgid "seconds." +msgstr "秒以后。" + +msgid "wrtbwmon is not installed!" +msgstr "wrtbwmon插件尚未安装" + +msgid "." +msgstr "。" diff --git a/package/ctcgfw/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon b/package/ctcgfw/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon new file mode 100755 index 0000000000..97ada9bccd --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon @@ -0,0 +1,11 @@ +#!/bin/sh + +uci -q batch <<-EOF >/dev/null + delete ucitrack.@wrtbwmon[-1] + add ucitrack wrtbwmon + set ucitrack.@wrtbwmon[-1].init=wrtbwmon + commit ucitrack +EOF + +rm -f /tmp/luci-indexcache +exit 0 diff --git a/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/readDB.awk b/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/readDB.awk new file mode 100755 index 0000000000..2080fe5f79 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/readDB.awk @@ -0,0 +1,213 @@ +#!/usr/bin/awk + +function inInterfaces(host) { + return(interfaces ~ "(^| )" host "($| )") +} + +function newRule(arp_ip, ipt_cmd) { + # checking for existing rules shouldn't be necessary if newRule is + # always called after db is read, arp table is read, and existing + # iptables rules are read. + ipt_cmd=iptKey " -t mangle -j RETURN -s " arp_ip + system(ipt_cmd " -C RRDIPT_FORWARD 2>/dev/null || " ipt_cmd " -A RRDIPT_FORWARD") + ipt_cmd=iptKey " -t mangle -j RETURN -d " arp_ip + system(ipt_cmd " -C RRDIPT_FORWARD 2>/dev/null || " ipt_cmd " -A RRDIPT_FORWARD") +} + +function delRule(arp_ip, ipt_cmd) { + ipt_cmd=iptKey " -t mangle -D RRDIPT_FORWARD -j RETURN " + system(ipt_cmd "-s " arp_ip " 2>/dev/null") + system(ipt_cmd "-d " arp_ip " 2>/dev/null") +} + +function total(i) { + return(bw[i "/in"] + bw[i "/out"]) +} + +BEGIN { + if (ipv6) { + iptNF = 8 + iptKey = "ip6tables" + } else { + iptNF = 9 + iptKey = "iptables" + } +} + +/^#/ { # get DB filename + FS = "," + dbFile = FILENAME + next +} + +# data from database; first file +ARGIND==1 { #!@todo this doesn't help if the DB file is empty. + lb=$1 + + if (lb !~ "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$") next + + if (!(lb in mac)) { + mac[lb] = $1 + ip[lb] = $2 + inter[lb] = $3 + speed[lb "/in"] = 0 + speed[lb "/out"]= 0 + bw[lb "/in"] = $6 + bw[lb "/out"] = $7 + firstDate[lb] = $9 + lastDate[lb] = $10 + ignore[lb] = 1 + } else { + if ($9 < firstDate[lb]) + firstDate[lb] = $9 + if ($10 > lastDate[lb]) { + ip[lb] = $2 + inter[lb] = $3 + lastDate[lb] = $10 + } + bw[lb "/in"] += $6 + bw[lb "/out"] += $7 + ignore[lb] = 0 + } + next +} + +# not triggered on the first file +FNR==1 { + FS=" " + if(ARGIND == 2) next +} + +# arp: ip hw flags hw_addr mask device +ARGIND==2 { + #!@todo regex match IPs and MACs for sanity + if (ipv6) { + statFlag= ($4 != "FAILED" && $4 != "INCOMPLETE") + macAddr = $5 + hwIF = $3 + } else { + statFlag= ($3 != "0x0") + macAddr = $4 + hwIF = $6 + } + + lb=$1 + if (hwIF != wanIF && statFlag && macAddr ~ "^([0-9a-fA-F]{2}:){5}[0-9a-fA-F]{2}$") { + hosts[lb] = 1 + arp_mac[lb] = macAddr + arp_ip[lb] = $1 + arp_inter[lb] = hwIF + arp_bw[lb "/in"] = 0 + arp_bw[lb "/out"] = 0 + arp_firstDate[lb] = systime() + arp_lastDate[lb] = arp_firstDate[lb] + arp_ignore[lb] = 1 + } + next +} + +#!@todo could use mangle chain totals or tailing "unnact" rules to +# account for data for new hosts from their first presence on the +# network to rule creation. The "unnact" rules would have to be +# maintained at the end of the list, and new rules would be inserted +# at the top. +ARGIND==3 && NF==iptNF && $1!="pkts" { # iptables input + if (ipv6) { + lfn = 5 + tag = "::/0" + } else { + lfn = 6 + tag = "0.0.0.0/0" + } + + if ($(lfn) != "*") { + m = $(lfn) + n = m "/in" + } else if ($(++lfn) != "*") { + m = $(lfn) + n = m "/out" + } else if ($(++lfn) != tag) { + m = $(lfn) + n = m "/out" + } else { # $(++lfn) != tag + m = $(++lfn) + n = m "/in" + } + + if (mode == "diff" || mode == "noUpdate") print n, $2 + if (mode != "noUpdate") { + if (inInterfaces(m)) { # if label is an interface + if (!(m in arp_mac)) { + cmd = "cat /sys/class/net/" m "/address" + cmd | getline arp_mac[m] + close(cmd) + + if (length(arp_mac[m]) == 0) arp_mac[m] = "00:00:00:00:00:00" + + arp_ip[m] = "NA" + arp_inter[m] = m + arp_bw[m "/in"] = 0 + arp_bw[m "/out"] = 0 + arp_firstDate[m] = systime() + arp_lastDate[m] = arp_firstDate[m] + arp_ignore[lb] = 1 + } + } else { + if (!(m in arp_mac)) hosts[m] = 0 + else delete hosts[m] + } + + if ($2 > 0) { + arp_bw[n] = $2 + arp_lastDate[m] = systime() + arp_ignore[m] = 0 + } + } +} + +END { + if (mode == "noUpdate") exit + + for (i in arp_ip) { + lb = arp_mac[i] + if (!arp_ignore[i] || !(lb in mac)) { + ignore[lb] = 0 + + if (lb in mac) { + bw[lb "/in"] += arp_bw[i "/in"] + bw[lb "/out"] += arp_bw[i "/out"] + lastDate[lb] = arp_lastDate[i] + } else { + bw[lb "/in"] = arp_bw[i "/in"] + bw[lb "/out"] = arp_bw[i "/out"] + firstDate[lb] = arp_firstDate[i] + lastDate[lb] = arp_lastDate[i] + } + mac[lb] = arp_mac[i] + ip[lb] = arp_ip[i] + inter[lb] = arp_inter[i] + + if (interval != 0) { + speed[lb "/in"] = int(arp_bw[i "/in"] / interval) + speed[lb "/out"]= int(arp_bw[i "/out"] / interval) + } + } + } + + close(dbFile) + for (i in mac) { + if (!ignore[i]) { + print "#mac,ip,iface,speed_in,speed_out,in,out,total,first_date,last_date" > dbFile + OFS="," + for (i in mac) + print mac[i], ip[i], inter[i], speed[i "/in"], speed[i "/out"], bw[i "/in"], bw[i "/out"], total(i), firstDate[i], lastDate[i] > dbFile + close(dbFile) + break + } + } + + # for hosts without rules + for (i in hosts) + if (hosts[i]) newRule(i) + else delRule(i) +} diff --git a/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/wrtbwmon b/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/wrtbwmon new file mode 100755 index 0000000000..91089a1eee --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/wrtbwmon @@ -0,0 +1,460 @@ +#!/bin/sh +# + +# Default input parameters for wrtbwmon. +runMode=0 +Monitor46=4 + +# Some parameters for monitor process. +for46= +updatePID= +logFile=/var/log/wrtbwmon.log +lockFile=/var/lock/wrtbwmon.lock +pidFile=/var/run/wrtbwmon.pid +tmpDir=/var/tmp/wrtbwmon +interval4=0 +interval6=0 + +# Debug parameters for readDB.awk. +mode= +DEBUG= + +# Constant parameter for wrtbwmon. +binDir=/usr/sbin +dataDir=/usr/share/wrtbwmon + +networkFuncs=/lib/functions/network.sh +uci=`which uci 2>/dev/null` +nslookup=`which nslookup 2>/dev/null` +nvram=`which nvram 2>/dev/null` + +chains='INPUT OUTPUT FORWARD' +interfaces='eth0 tun0 br-lan' # in addition to detected WAN + +# DNS server for reverse lookups provided in "DNS". +# don't perform reverse DNS lookups by default +DO_RDNS=${DNS-} + +header="#mac,ip,iface,speed_in,speed_out,in,out,total,first_date,last_date" + +createDbIfMissing() { + [ ! -f "$DB" ] && echo $header > "$DB" + [ ! -f "$DB6" ] && echo $header > "$DB6" +} + +checkDbArg() { + [ -z "$DB" ] && echo "ERROR: Missing argument 2 (database file)" && exit 1 +} + +checkDB() { + [ ! -f "$DB" ] && echo "ERROR: $DB does not exist" && exit 1 + [ ! -w "$DB" ] && echo "ERROR: $DB is not writable" && exit 1 + [ ! -f "$DB6" ] && echo "ERROR: $DB6 does not exist" && exit 1 + [ ! -w "$DB6" ] && echo "ERROR: $DB6 is not writable" && exit 1 +} + +checkWAN() { + [ -z "$1" ] && echo "Warning: failed to detect WAN interface." +} + +lookup() { + local MAC=$1 + local IP=$2 + local userDB=$3 + local USERSFILE= + local USER= + for USERSFILE in $userDB /tmp/dhcp.leases /tmp/dnsmasq.conf /etc/dnsmasq.conf /etc/hosts; do + [ -e "$USERSFILE" ] || continue + + case $USERSFILE in + /tmp/dhcp.leases ) + USER=$(grep -i "$MAC" $USERSFILE | cut -f4 -s -d' ') + ;; + /etc/hosts ) + USER=$(grep "^$IP " $USERSFILE | cut -f2 -s -d' ') + ;; + * ) + USER=$(grep -i "$MAC" "$USERSFILE" | cut -f2 -s -d,) + ;; + esac + + [ "$USER" = "*" ] && USER= + [ -n "$USER" ] && break + + done + + if [ -n "$DO_RDNS" -a -z "$USER" -a "$IP" != "NA" -a -n "$nslookup" ]; then + USER=`$nslookup $IP $DNS | awk '!/server can/{if($4){print $4; exit}}' | sed -re 's/[.]$//'` + fi + + [ -z "$USER" ] && USER=${MAC} + echo $USER +} + +detectIF() { + local IF= + if [ -f "$networkFuncs" ]; then + IF=`. $networkFuncs; network_get_device netdev $1; echo $netdev` + [ -n "$IF" ] && echo $IF && return + fi + + if [ -n "$uci" -a -x "$uci" ]; then + IF=`$uci get network.${1}.ifname 2>/dev/null` + [ $? -eq 0 -a -n "$IF" ] && echo $IF && return + fi + + if [ -n "$nvram" -a -x "$nvram" ]; then + IF=`$nvram get ${1}_ifname 2>/dev/null` + [ $? -eq 0 -a -n "$IF" ] && echo $IF && return + fi +} + +detectLAN() { + [ -e /sys/class/net/br-lan ] && echo br-lan && return + local lan=$(detectIF lan) + [ -n "$lan" ] && echo $lan && return +} + +detectWAN() { + local wan=$(detectIF wan) + [ -n "$wan" ] && echo $wan && return + wan=$(ip route show 2>/dev/null | grep default | sed -re '/^default/ s/default.*dev +([^ ]+).*/\1/') + [ -n "$wan" ] && echo $wan && return + [ -f "$networkFuncs" ] && wan=$(. $networkFuncs; network_find_wan wan; echo $wan) + [ -n "$wan" ] && echo $wan && return +} + +lockFunc() { + #Realize the lock function by busybox lock or flock command. + # if !(lock -n $lockFile) >/dev/null 2>&1; then + # exit 1 + # fi + #The following lock method is realized by other's function. + + local attempts=0 + local flag=0 + + while [ "$flag" = 0 ]; do + local tempfile=$(mktemp $tmpDir/lock.XXXXXX) + ln $tempfile $lockFile >/dev/null 2>&1 && flag=1 + rm $tempfile + + if [ "$flag" = 1 ]; then + [ -n "$DEBUG" ] && echo ${updatePID} "got lock after $attempts attempts" + flag=1 + else + sleep 1 + attempts=$(($attempts+1)) + [ -n "$DEBUG" ] && echo ${updatePID} "The $attempts attempts." + [ "$attempts" -ge 10 ] && exit + fi + done +} + +unlockFunc() { + #Realize the lock function by busybox lock or flock command. + # lock -u $lockFile + # rm -f $lockFile + # [ -n "$DEBUG" ] && echo ${updatePID} "released lock" + #The following lock method is realized by other's function. + + rm -f $lockFile + [ -n "$DEBUG" ] && echo ${updatePID} "released lock" +} + +# chain +newChain() { + local chain=$1 + local ipt=$2 + # Create the RRDIPT_$chain chain (it doesn't matter if it already exists). + + $ipt -t mangle -N RRDIPT_$chain 2> /dev/null + + # Add the RRDIPT_$chain CHAIN to the $chain chain if not present + $ipt -t mangle -C $chain -j RRDIPT_$chain 2>/dev/null + if [ $? -ne 0 ]; then + [ -n "$DEBUG" ] && echo "DEBUG: $ipt chain misplaced, recreating it..." + $ipt -t mangle -I $chain -j RRDIPT_$chain + fi +} + +# chain tun +newRuleIF() { + local chain=$1 + local IF=$2 + local ipt=$3 + local cmd= + + if [ "$chain" = "OUTPUT" ]; then + cmd="$ipt -t mangle -o $IF -j RETURN" + elif [ "$chain" = "INPUT" ]; then + cmd="$ipt -t mangle -i $IF -j RETURN" + fi + [ -n "$cmd" ] && eval $cmd " -C RRDIPT_$chain 2>/dev/null" || eval $cmd " -A RRDIPT_$chain" +} + +publish() { + # sort DB + # busybox sort truncates numbers to 32 bits + grep -v '^#' $DB | awk -F, '{OFS=","; a=sprintf("%f",$6/1e6); $6=""; print a,$0}' | tr -s ',' | sort -rn | awk -F, '{OFS=",";$1=sprintf("%f",$1*1e6);print}' > $tmpDir/sorted_${updatePID}.tmp + + # create HTML page + local htmPage="$tmpDir/${pb_html##*/}" + rm -f $htmPage + cp $dataDir/usage.htm1 $htmPage + + while IFS=, read PEAKUSAGE_IN MAC IP IFACE SPEED_IN SPEED_OUT PEAKUSAGE_OUT TOTAL FIRSTSEEN LASTSEEN + do + echo " +new Array(\"$(lookup $MAC $IP $user_def)\",\"$MAC\",\"$IP\",$SPEED_IN,$SPEED_OUT, +$PEAKUSAGE_IN,$PEAKUSAGE_OUT,$TOTAL,\"$FIRSTSEEN\",\"$LASTSEEN\")," >> $htmPage + done < $tmpDir/sorted_${updatePID}.tmp + echo "0);" >> $htmPage + + sed "s/(date)/`date`/" < $dataDir/usage.htm2 >> $htmPage + mv $htmPage "$pb_html" +} + +updatePrepare() { + checkDbArg + createDbIfMissing + checkDB + [ -e $tmpDir ] || mkdir -p $tmpDir + + for46="$Monitor46" + local timeNow=$(cat /proc/uptime | awk '{print $1}') + + if [ -e "$logFile" ]; then + local timeLast4=$(awk -F'[: ]+' '/ipv4/{print $2}' "$logFile") + local timeLast6=$(awk -F'[: ]+' '/ipv6/{print $2}' "$logFile") + interval4=$(awk -v now=$timeNow -v last=$timeLast4 'BEGIN{print (now-last)}'); + interval6=$(awk -v now=$timeNow -v last=$timeLast6 'BEGIN{print (now-last)}'); + + for ii in 4 6; do + [[ -n "$(echo $for46 | grep ${ii})" ]] && { + if [[ "$(eval echo \$interval${ii})" \> "0.9" ]]; then + sed -i "s/^ipv${ii}: [0-9\.]\{1,\}/ipv${ii}: $timeNow/ig" "$logFile" + else + for46=`echo "$for46" | sed "s/${ii}//g"` + fi + } + done + else + echo -e "ipv4: $timeNow\nipv6: $timeNow" >"$logFile" + fi + return 0 +} + +update() { + updatePID=$( sh -c 'echo $PPID' ) + + lockFunc + + local wan=$(detectWAN) + checkWAN $wan + interfaces="$interfaces $wan" + + [ "$for46" = 4 ] && IPT='iptables' + [ "$for46" = 6 ] && IPT='ip6tables' + [ "$for46" = 46 ] && IPT='iptables ip6tables' + + for ii in $IPT ; do + if [ -z "$( ${ii}-save | grep RRDIPT )" ]; then + + for chain in $chains; do + newChain $chain $ii + done + + # track local data + for chain in INPUT OUTPUT; do + for interface in $interfaces; do + [ -n "$interface" ] && [ -e "/sys/class/net/$interface" ] && newRuleIF $chain $interface $ii + done + done + fi + # this will add rules for hosts in arp table + > $tmpDir/${ii}_${updatePID}.tmp + + for chain in $chains; do + $ii -nvxL RRDIPT_$chain -t mangle -Z >> $tmpDir/${ii}_${updatePID}.tmp + done + done + + [ -f $tmpDir/iptables_${updatePID}.tmp ] && ( + awk -v mode="$mode" -v interfaces="$interfaces" -v wanIF="$wan" -v interval=$interval4 \ + -v ipv6="0" -f $binDir/readDB.awk \ + $DB \ + /proc/net/arp \ + $tmpDir/iptables_${updatePID}.tmp + ) + + [ -f $tmpDir/ip6tables_${updatePID}.tmp ] && ( + echo "This file is geneated by 'ip -6 neigh'" > $tmpDir/ip6addr_${updatePID}.tmp + `ip -6 neigh >> $tmpDir/ip6addr_${updatePID}.tmp`; + + awk -v mode="$mode" -v interfaces="$interfaces" -v wanIF="$wan" -v interval=$interval6 \ + -v ipv6="1" -f $binDir/readDB.awk \ + "$DB6" \ + $tmpDir/ip6addr_${updatePID}.tmp \ + $tmpDir/ip6tables_${updatePID}.tmp + ) + + [ "$Monitor46" = 46 ] && ( + cp $DB $DB46 + cat $DB6 >> $DB46 + awk -f $binDir/readDB.awk "$DB46" + ) + + [ -n "$pb_html" ] && publish + + rm -f $tmpDir/*_${updatePID}.tmp + unlockFunc +} + +renamefile() { + local base=$(basename -- "$1") + local ext=$([ -z "${base/*.*/}" ] && echo ".${base##*.}" || echo '') + local base="${base%.*}" + echo "$(dirname $1)/${base}$2$ext" && return +} + +ending() { + iptables-save | grep -v RRDIPT | iptables-restore + ip6tables-save | grep -v RRDIPT | ip6tables-restore + + if checkPid $pidFile; then + local pid=$( cat $pidFile ) + rm -rf $lockFile $logFile $pidFile $tmpDir/* + kill -9 $pid >> /dev/null 2>&1 + fi + echo "exit!!" +} + +checkPid() { + [ -e "$1" ] && local pid=$(cat $1) || return 1 + [ -d "/proc/$pid" ] && { + [ -n "$( cat /proc/$pid/cmdline | grep wrtbwmon )" ] && return 0 + } + return 1 +} + +sleepProcess() { + sleep 1m + kill -CONT $1 >>/dev/null 2>&1 +} + +loop() { + trap 'ending' INT TERM HUP QUIT + if checkPid $pidFile; then + echo "Another wrtbwmon is on running!!!" + else + local loopPID=$( sh -c 'echo $PPID' ) + local SPID= + echo $loopPID > $pidFile + while true ;do + [ -n "$SPID" ] && kill -9 $SPID >>/dev/null 2>&1 + sleepProcess $loopPID & + SPID=$! + updatePrepare && update + kill -STOP $loopPID >>/dev/null 2>&1 + done + fi + trap INT TERM HUP QUIT +} + +tips() { + echo \ +"Usage: $0 [options...] +Options: + -k Exit the wrtbwmon! + -f dbfile Set the DB file path + -u usrfile Set the user_def file path + -p htmlfile Set the publish htm file path + -d Enter the foreground mode. + -D Enter the daemo mode. + -4 Listen to ipv4 only. + -6 Listen to ipv6 only. + -46 Listen to ipv4 and ipv6. + +Note: [user_file] is an optional file to match users with MAC addresses. + Its format is \"00:MA:CA:DD:RE:SS,username\", with one entry per line." +} + +############################################################ + +while [ $# != 0 ];do + case $1 in + "-k" ) + /etc/init.d/wrtbwmon stop + exit 0 + ;; + "-f" ) + shift + if [ $# -gt 0 ];then + DB=$1 + DB6="$(renamefile $DB .6)" + DB46="$(renamefile $DB .46)" + else + echo "No db file path seted, exit!!" + exit 1 + fi + ;; + "-u") + shift + if [ $# -gt 0 ];then + user_def=$1 + else + echo "No user define file path seted, exit!!" + exit 1 + fi + ;; + + "-p") + shift + if [ $# -gt 0 ];then + pb_html=$1 + else + echo "No publish html file path seted, exit!!" + exit 1 + fi + ;; + + "-d") + runMode=1 + ;; + + "-D") + runMode=2 + ;; + + "-4") + Monitor46=4 + ;; + + "-6") + Monitor46=6 + ;; + + "-46") + Monitor46=46 + ;; + + "&&" | "||" | ";") + break + ;; + + "*") + tips + ;; + esac + + shift +done + +if [ "$runMode" = '1' ]; then + loop +elif [ "$runMode" = '2' ]; then + loop >>/dev/null 2>&1 & +else + updatePrepare && update +fi diff --git a/package/ctcgfw/luci-app-wrtbwmon/usr/share/wrtbwmon/usage.htm1 b/package/ctcgfw/luci-app-wrtbwmon/usr/share/wrtbwmon/usage.htm1 new file mode 100644 index 0000000000..c469cb7d91 --- /dev/null +++ b/package/ctcgfw/luci-app-wrtbwmon/usr/share/wrtbwmon/usage.htm1 @@ -0,0 +1,34 @@ +Traffic + +

Total Usage:

+ + + + + + + + + + + +
UserDown SpeedUp SpeedDownloadUploadTotalFirst seenLast seen
+
This page was generated on (date) + diff --git a/package/lean/luci-app-wrtbwmon/Makefile b/package/lean/luci-app-wrtbwmon/Makefile deleted file mode 100644 index 412b35fe52..0000000000 --- a/package/lean/luci-app-wrtbwmon/Makefile +++ /dev/null @@ -1,17 +0,0 @@ -# Copyright (C) 2016 Openwrt.org -# -# This is free software, licensed under the Apache License, Version 2.0 . -# - -include $(TOPDIR)/rules.mk - -LUCI_TITLE:=LuCI support for Wrtbwmon -LUCI_DEPENDS:=+luci-app-nlbwmon -LUCI_PKGARCH:=all -PKG_VERSION:=1.0 -PKG_RELEASE:=7 - -include $(TOPDIR)/feeds/luci/luci.mk - -# call BuildPackage - OpenWrt buildroot signature - diff --git a/package/lean/luci-app-wrtbwmon/htdocs/luci-static/wrtbwmon.js b/package/lean/luci-app-wrtbwmon/htdocs/luci-static/wrtbwmon.js deleted file mode 100644 index 36812e723b..0000000000 --- a/package/lean/luci-app-wrtbwmon/htdocs/luci-static/wrtbwmon.js +++ /dev/null @@ -1,562 +0,0 @@ -var wrt = { - // variables for auto-update, interval is in seconds - scheduleTimeout: undefined, - updateTimeout: undefined, - isScheduled: true, - interval: 5, - // option on whether to show per host sub-totals - perHostTotals: false, - // variables for sorting - sortData: { - column: 7, - elId: 'thTotal', - dir: 'desc', - cache: {} - } -}; - -(function () { - var oldDate, oldValues = []; - - // find base path - var re = /(.*?admin\/nlbw\/[^/]+)/; - var basePath = window.location.pathname.match(re)[1]; - - //---------------------- - // HELPER FUNCTIONS - //---------------------- - - /** - * Human readable text for size - * @param size - * @returns {string} - */ - function getSize(size) { - var prefix = [' ', 'k', 'M', 'G', 'T', 'P', 'E', 'Z']; - var precision, base = 1000, pos = 0; - while (size > base) { - size /= base; - pos++; - } - if (pos > 2) precision = 1000; else precision = 1; - return (Math.round(size * precision) / precision) + ' ' + prefix[pos] + 'B'; - } - - /** - * Human readable text for date - * @param date - * @returns {string} - */ - function dateToString(date) { - return date.toString().substring(0, 24); - } - - /** - * Gets the string representation of the date received from BE - * @param value - * @returns {*} - */ - function getDateString(value) { - var tmp = value.split('_'), - str = tmp[0].split('-').reverse().join('-') + 'T' + tmp[1]; - return dateToString(new Date(str)); - } - - /** - * Create a `tr` element with content - * @param content - * @returns {string} - */ - function createTR(content) { - var res = '' + data[2], {title: data[1]}), - createTD(getSize(dlSpeed) + '/s', {right: true}), - createTD(getSize(upSpeed) + '/s', {right: true}), - createTD(getSize(data[3]), {right: true}), - createTD(getSize(data[4]), {right: true}), - createTD(getSize(data[5]), {right: true}), - createTD(getDateString(data[6])), - createTD(getDateString(data[7])) - ]; - - // display row data - var result = ''; - for (var k = 0; k < displayData.length; k++) { - result += displayData[k]; - } - result = createTR(result); - return [result, rowData]; - } - - /** - * Creates the HTML output based on the `data` and `totals` inputs - * @param data - * @param totals - * @returns {string} HTML output - */ - function getDisplayData(data, totals) { - var result = - createTH('客户端', {id: 'thClient'}) + - createTH('下载带宽', {id: 'thDownload'}) + - createTH('上传带宽', {id: 'thUpload'}) + - createTH('总下载流量', {id: 'thTotalDown'}) + - createTH('总上传流量', {id: 'thTotalUp'}) + - createTH('流量合计', {id: 'thTotal'}) + - createTH('首次上线时间', {id: 'thFirstSeen'}) + - createTH('最后上线时间', {id: 'thLastSeen'}); - result = createTR(result); - for (var k = 0; k < data.length; k++) { - result += data[k][0]; - } - var totalsRow = createTH('总计'); - for (var m = 0; m < totals.length; m++) { - var t = totals[m]; - totalsRow += createTD(getSize(t) + (m < 2 ? '/s' : ''), {right: true}); - } - result += createTR(totalsRow); - return result; - } - - /** - * Calculates per host sub-totals and adds them in the data input - * @param data The data input - */ - function aggregateHostTotals(data) { - if (!wrt.perHostTotals) return; - - var curHost = 0, insertAt = 1; - while (curHost < data.length && insertAt < data.length) { - // grab the current hostname/mac, and walk the data looking for rows with the same host/mac - var hostName = data[curHost][1][0].toLowerCase(); - for (var k = curHost + 1; k < data.length; k++) { - if (data[k][1][0].toLowerCase() === hostName) { - // this is another row for the same host, group it with any other rows for this host - data.splice(insertAt, 0, data.splice(k, 1)[0]); - insertAt++; - } - } - - // if we found more than one row for the host, add a subtotal row - if (insertAt > curHost + 1) { - var hostTotals = [data[curHost][1][0], '', '', 0, 0, 0, 0, 0]; - for (var i = curHost; i < insertAt && i < data.length; i++) { - for (var j = 3; j < hostTotals.length; j++) { - hostTotals[j] += data[i][1][j]; - } - } - var hostTotalRow = createTH(data[curHost][1][0] + '
(host total)', {title: data[curHost][1][1]}); - for (var m = 3; m < hostTotals.length; m++) { - var t = hostTotals[m]; - hostTotalRow += createTD(getSize(t) + (m < 5 ? '/s' : ''), {right: true}); - } - hostTotalRow = createTR(hostTotalRow); - data.splice(insertAt, 0, [hostTotalRow, hostTotals]); - } - curHost = insertAt; - insertAt = curHost + 1; - } - } - - /** - * Sorting function used to sort the `data`. Uses the global sort settings - * @param x first item to compare - * @param y second item to compare - * @returns {number} 1 for desc, -1 for asc, 0 for equal - */ - function sortingFunction(x, y) { - // get data from global variable - var sortColumn = wrt.sortData.column, sortDirection = wrt.sortData.dir; - var a = x[1][sortColumn]; - var b = y[1][sortColumn]; - if (a === b) { - return 0; - } else if (sortDirection === 'desc') { - return a < b ? 1 : -1; - } else { - return a > b ? 1 : -1; - } - } - - /** - * Sets the relevant global sort variables and re-renders the table to apply the new sorting - * @param elId - * @param column - */ - function setSortColumn(elId, column) { - if (column === wrt.sortData.column) { - // same column clicked, switch direction - wrt.sortData.dir = wrt.sortData.dir === 'desc' ? 'asc' : 'desc'; - } else { - // change sort column - wrt.sortData.column = column; - // reset sort direction - wrt.sortData.dir = 'desc'; - } - wrt.sortData.elId = elId; - - // render table data from cache - renderTableData(wrt.sortData.cache.data, wrt.sortData.cache.totals); - } - - /** - * Registers the table events handlers for sorting when clicking the column headers - */ - function registerTableEventHandlers() { - // note these ordinals are into the data array, not the table output - document.getElementById('thClient').addEventListener('click', function () { - setSortColumn(this.id, 0); // hostname - }); - document.getElementById('thDownload').addEventListener('click', function () { - setSortColumn(this.id, 3); // dl speed - }); - document.getElementById('thUpload').addEventListener('click', function () { - setSortColumn(this.id, 4); // ul speed - }); - document.getElementById('thTotalDown').addEventListener('click', function () { - setSortColumn(this.id, 5); // total down - }); - document.getElementById('thTotalUp').addEventListener('click', function () { - setSortColumn(this.id, 6); // total up - }); - document.getElementById('thTotal').addEventListener('click', function () { - setSortColumn(this.id, 7); // total - }); - } - - /** - * Fetches and handles the updated `values` from the BE - * @param once If set to true, it re-schedules itself for execution based on selected interval - */ - function receiveData(once) { - var ajax = new XMLHttpRequest(); - ajax.onreadystatechange = function () { - // noinspection EqualityComparisonWithCoercionJS - if (this.readyState == 4 && this.status == 200) { - var re = /(var values = new Array[^;]*;)/, - match = ajax.responseText.match(re); - if (!match) { - handleError(); - } else { - // evaluate values - eval(match[1]); - //noinspection JSUnresolvedVariable - var v = values; - if (!v) { - handleError(); - } else { - handleValues(v); - // set old values - oldValues = v; - // set old date - oldDate = new Date(); - document.getElementById('updated').innerHTML = '数据更新时间 ' + dateToString(oldDate); - } - } - var int = wrt.interval; - if (!once && int > 0) reschedule(int); - } - }; - ajax.open('GET', basePath + '/usage_data', true); - ajax.send(); - } - - /** - * Registers DOM event listeners for user interaction - */ - function addEventListeners() { - document.getElementById('intervalSelect').addEventListener('change', function () { - var int = wrt.interval = this.value; - if (int > 0) { - // it is not scheduled, schedule it - if (!wrt.isScheduled) { - reschedule(int); - } - } else { - // stop the scheduling - stopSchedule(); - } - }); - - document.getElementById('resetDatabase').addEventListener('click', function () { - if (confirm('This will delete the database file. Are you sure?')) { - var ajax = new XMLHttpRequest(); - ajax.onreadystatechange = function () { - // noinspection EqualityComparisonWithCoercionJS - if (this.readyState == 4 && this.status == 204) { - location.reload(); - } - }; - ajax.open('GET', basePath + '/usage_reset', true); - ajax.send(); - } - }); - - document.getElementById('perHostTotals').addEventListener('change', function () { - wrt.perHostTotals = !wrt.perHostTotals; - }); - } - - //---------------------- - // AUTO-UPDATE - //---------------------- - - /** - * Stop auto-update schedule - */ - function stopSchedule() { - window.clearTimeout(wrt.scheduleTimeout); - window.clearTimeout(wrt.updateTimeout); - setUpdateMessage(''); - wrt.isScheduled = false; - } - - /** - * Start auto-update schedule - * @param seconds - */ - function reschedule(seconds) { - wrt.isScheduled = true; - seconds = seconds || 60; - updateSeconds(seconds); - wrt.scheduleTimeout = window.setTimeout(receiveData, seconds * 1000); - } - - /** - * Sets the text of the `#updating` element - * @param msg - */ - function setUpdateMessage(msg) { - document.getElementById('updating').innerHTML = msg; - } - - /** - * Updates the 'Updating in X seconds' message - * @param start - */ - function updateSeconds(start) { - setUpdateMessage('倒数 ' + start + ' 秒后刷新.'); - if (start > 0) { - wrt.updateTimeout = window.setTimeout(function () { - updateSeconds(start - 1); - }, 1000); - } - } - - //---------------------- - // END AUTO-UPDATE - //---------------------- - - /** - * Check for dependency, and if all is well, run callback - * @param cb Callback function - */ - function checkForDependency(cb) { - var ajax = new XMLHttpRequest(); - ajax.onreadystatechange = function () { - // noinspection EqualityComparisonWithCoercionJS - if (this.readyState == 4 && this.status == 200) { - // noinspection EqualityComparisonWithCoercionJS - if (ajax.responseText == "1") { - cb(); - } else { - alert("wrtbwmon is not installed!"); - } - } - }; - ajax.open('GET', basePath + '/check_dependency', true); - ajax.send(); - } - - checkForDependency(function () { - // register events - addEventListeners(); - // Main entry point - receiveData(); - }); - -})(); diff --git a/package/lean/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua b/package/lean/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua deleted file mode 100644 index 25909c846d..0000000000 --- a/package/lean/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua +++ /dev/null @@ -1,43 +0,0 @@ -module("luci.controller.wrtbwmon", package.seeall) - -function index() - entry({"admin", "nlbw", "usage"}, alias("admin", "nlbw", "usage", "details"), _("Usage"), 60) - entry({"admin", "nlbw", "usage", "details"}, template("wrtbwmon"), _("Details"), 10).leaf=true - entry({"admin", "nlbw", "usage", "config"}, cbi("wrtbwmon/config"), _("Configuration"), 20).leaf=true - entry({"admin", "nlbw", "usage", "custom"}, form("wrtbwmon/custom"), _("User file"), 30).leaf=true - entry({"admin", "nlbw", "usage", "check_dependency"}, call("check_dependency")).dependent=true - entry({"admin", "nlbw", "usage", "usage_data"}, call("usage_data")).dependent=true - entry({"admin", "nlbw", "usage", "usage_reset"}, call("usage_reset")).dependent=true -end - -function usage_database_path() - local cursor = luci.model.uci.cursor() - if cursor:get("wrtbwmon", "general", "persist") == "1" then - return "/etc/config/usage.db" - else - return "/tmp/usage.db" - end -end - -function check_dependency() - local ret = "0" - if require("luci.model.ipkg").installed('iptables') then - ret = "1" - end - luci.http.prepare_content("text/plain") - luci.http.write(ret) -end - -function usage_data() - local db = usage_database_path() - local publish_cmd = "wrtbwmon publish " .. db .. " /tmp/usage.htm /etc/config/wrtbwmon.user" - local cmd = "wrtbwmon update " .. db .. " && " .. publish_cmd .. " && cat /tmp/usage.htm" - luci.http.prepare_content("text/html") - luci.http.write(luci.sys.exec(cmd)) -end - -function usage_reset() - local db = usage_database_path() - local ret = luci.sys.call("wrtbwmon update " .. db .. " && rm " .. db) - luci.http.status(204) -end diff --git a/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua b/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua deleted file mode 100644 index 469d4f8f2c..0000000000 --- a/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua +++ /dev/null @@ -1,18 +0,0 @@ -local m = Map("wrtbwmon", translate("Details")) - -local s = m:section(NamedSection, "general", "wrtbwmon", translate("General settings")) - -local o = s:option(Flag, "persist", translate("Persist database"), - translate("Check this to persist the database file")) -o.rmempty = false - -function o.write(self, section, value) - if value == '1' then - luci.sys.call("mv /tmp/usage.db /etc/config/usage.db") - elseif value == '0' then - luci.sys.call("mv /etc/config/usage.db /tmp/usage.db") - end - return Flag.write(self, section ,value) -end - -return m diff --git a/package/lean/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm b/package/lean/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm deleted file mode 100644 index 68713b1238..0000000000 --- a/package/lean/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm +++ /dev/null @@ -1,46 +0,0 @@ -<%+header%> -

<%=translate("Usage")%>

-

- -

-

- - - -
- - -
-

- - -
<%=translate("Loading...")%>
- - -<%+footer%> diff --git a/package/lean/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po b/package/lean/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po deleted file mode 100644 index 3eb050e3f4..0000000000 --- a/package/lean/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po +++ /dev/null @@ -1,56 +0,0 @@ -msgid "" -msgstr "Content-Type: text/plain; charset=UTF-8" - -msgid "Usage" -msgstr "实时流量监测" - -msgid "Details" -msgstr "详细信息" - -msgid "Configuration" -msgstr "配置" - -msgid "User file" -msgstr "自定义主机信息" - -msgid "Usage - Configuration" -msgstr "详细设置" - -msgid "General settings" -msgstr "通用设置" - -msgid "Persist database" -msgstr "写入数据库到硬盘" - -msgid "Check this to persist the database file" -msgstr "把统计数据写入 /etc/config 中避免重启或者升级后丢失" - -msgid "Usage - Custom User File" -msgstr "自定义MAC地址对应的主机名" - -msgid "This file is used to match users with MAC addresses and it must have the following format: 00:aa:bb:cc:ee:ff,username" -msgstr "每一行的格式为 00:aa:bb:cc:ee:ff,username" - -msgid "Reset Database" -msgstr "重置数据库" - -msgid "Auto Refresh Interval" -msgstr "自动刷新间隔" - -msgid "Disabled" -msgstr "禁用" - -msgid "Second" -msgstr "秒" - -msgid "Seconds" -msgstr "秒" - -msgid "Minutes" -msgstr "分钟" - -msgid "Per-host Totals" -msgstr "合并每一客户端数据" - -msgid "Loading..." -msgstr "加载中..." diff --git a/package/lean/luci-app-wrtbwmon/root/etc/config/wrtbwmon b/package/lean/luci-app-wrtbwmon/root/etc/config/wrtbwmon deleted file mode 100644 index 419270dbab..0000000000 --- a/package/lean/luci-app-wrtbwmon/root/etc/config/wrtbwmon +++ /dev/null @@ -1,4 +0,0 @@ - -config wrtbwmon 'general' - option persist '0' - diff --git a/package/lean/luci-app-wrtbwmon/root/etc/init.d/wrtbwmon b/package/lean/luci-app-wrtbwmon/root/etc/init.d/wrtbwmon deleted file mode 100755 index d57c09ae1d..0000000000 --- a/package/lean/luci-app-wrtbwmon/root/etc/init.d/wrtbwmon +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/sh /etc/rc.common -# -# start/stop wrtbwmon bandwidth monitor - -### BEGIN INIT INFO -# Provides: wrtbwmon -# Required-Start: $network $local_fs $remote_fs -# Required-Stop: $local_fs $remote_fs -# Default-Start: 2 3 4 5 -# Default-Stop: 0 1 6 -# Short-Description: iptables-based bandwidth monitor -### END INIT INFO - -START=91 - -start(){ - /usr/sbin/wrtbwmon setup /tmp/usage.db -} - -stop(){ - /usr/sbin/wrtbwmon remove -} diff --git a/package/lean/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon b/package/lean/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon deleted file mode 100755 index bcb5b337f3..0000000000 --- a/package/lean/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon +++ /dev/null @@ -1,14 +0,0 @@ -#!/bin/sh - -uci -q batch <<-EOF >/dev/null - delete firewall.wrtbwmon - set firewall.wrtbwmon=include - set firewall.wrtbwmon.type=script - set firewall.wrtbwmon.path='/etc/wrtbwmon.include' - set firewall.wrtbwmon.reload=1 - commit firewall -EOF - -/etc/init.d/wrtbwmon enable -/etc/init.d/wrtbwmon start -exit 0 diff --git a/package/lean/luci-app-wrtbwmon/root/etc/wrtbwmon.include b/package/lean/luci-app-wrtbwmon/root/etc/wrtbwmon.include deleted file mode 100755 index 39bcf43a10..0000000000 --- a/package/lean/luci-app-wrtbwmon/root/etc/wrtbwmon.include +++ /dev/null @@ -1 +0,0 @@ -/etc/init.d/wrtbwmon restart >/dev/null 2>&1 diff --git a/package/lean/luci-app-wrtbwmon/root/usr/sbin/readDB.awk b/package/lean/luci-app-wrtbwmon/root/usr/sbin/readDB.awk deleted file mode 100755 index fe67e4ae8b..0000000000 --- a/package/lean/luci-app-wrtbwmon/root/usr/sbin/readDB.awk +++ /dev/null @@ -1,157 +0,0 @@ -#!/usr/bin/awk - -function inInterfaces(host){ - return(interfaces ~ "(^| )"host"($| )") -} - -function newRule(arp_ip, - ipt_cmd){ - # checking for existing rules shouldn't be necessary if newRule is - # always called after db is read, arp table is read, and existing - # iptables rules are read. - ipt_cmd="iptables -t mangle -j RETURN -s " arp_ip - system(ipt_cmd " -C RRDIPT_FORWARD 2>/dev/null || " ipt_cmd " -A RRDIPT_FORWARD") - ipt_cmd="iptables -t mangle -j RETURN -d " arp_ip - system(ipt_cmd " -C RRDIPT_FORWARD 2>/dev/null || " ipt_cmd " -A RRDIPT_FORWARD") -} - -function total(i){ - return(bw[i "/in"] + bw[i "/out"]) -} - -function date( cmd, d){ - cmd="date +%d-%m-%Y_%H:%M:%S" - cmd | getline d - close(cmd) - #!@todo could start a process with "while true; do date ...; done" - return(d) -} - -BEGIN { - od="" - fid=1 - debug=0 - rrd=0 -} - -/^#/ { # get DB filename - FS="," - dbFile=FILENAME - next -} - -# data from database; first file -FNR==NR { #!@todo this doesn't help if the DB file is empty. - if($2 == "NA") - #!@todo could get interface IP here - n=$1 - else - n=$2 - - hosts[n] = "" # add this host/interface to hosts - mac[n] = $1 - ip[n] = $2 - inter[n] = $3 - bw[n "/in"] = $4 - bw[n "/out"] = $5 - firstDate[n] = $7 - lastDate[n] = $8 - next -} - -# not triggered on the first file -FNR==1 { - FS=" " - fid++ #!@todo use fid for all files; may be problematic for empty files - next -} - -# arp: ip hw flags hw_addr mask device -fid==2 { - #!@todo regex match IPs and MACs for sanity - arp_ip = $1 - arp_flags = $3 - arp_mac = $4 - arp_dev = $6 - if(arp_flags != "0x0" && !(arp_ip in ip)){ - if(debug) - print "new host:", arp_ip, arp_flags > "/dev/stderr" - hosts[arp_ip] = "" - mac[arp_ip] = arp_mac - ip[arp_ip] = arp_ip - inter[arp_ip] = arp_dev - bw[arp_ip "/in"] = bw[arp_ip "/out"] = 0 - firstDate[arp_ip] = lastDate[arp_ip] = date() - } - next -} - -#!@todo could use mangle chain totals or tailing "unnact" rules to -# account for data for new hosts from their first presence on the -# network to rule creation. The "unnact" rules would have to be -# maintained at the end of the list, and new rules would be inserted -# at the top. - -# skip line -# read the chain name and deal with the data accordingly -fid==3 && $1 == "Chain"{ - rrd=$2 ~ /RRDIPT_.*/ - next -} - -fid==3 && rrd && (NF < 9 || $1=="pkts"){ next } - -fid==3 && rrd { # iptables input - if($6 != "*"){ - m=$6 - n=m "/out" - } else if($7 != "*"){ - m=$7 - n=m "/in" - } else if($8 != "0.0.0.0/0"){ - m=$8 - n=m "/out" - } else { # $9 != "0.0.0.0/0" - m=$9 - n=m "/in" - } - - # remove host from array; any hosts left in array at END get new - # iptables rules - - #!@todo this deletes a host if any rule exists; if only one - # directional rule is removed, this will not remedy the situation - delete hosts[m] - - if($2 > 0){ # counted some bytes - if(mode == "diff" || mode == "noUpdate") - print n, $2 - if(mode!="noUpdate"){ - if(inInterfaces(m)){ # if label is an interface - if(!(m in mac)){ # if label was not in db (also not in - # arp table, but interfaces won't be - # there anyway) - firstDate[m] = date() - mac[m] = inter[m] = m - ip[m] = "NA" - bw[m "/in"]=bw[m "/out"]= 0 - } - } - bw[n]+=$2 - lastDate[m] = date() - } - } -} - -END { - if(mode=="noUpdate") exit - close(dbFile) - system("rm -f " dbFile) - print "#mac,ip,iface,in,out,total,first_date,last_date" > dbFile - OFS="," - for(i in mac) - print mac[i], ip[i], inter[i], bw[i "/in"], bw[i "/out"], total(i), firstDate[i], lastDate[i] > dbFile - close(dbFile) - # for hosts without rules - for(host in hosts) if(!inInterfaces(host)) newRule(host) -} diff --git a/package/lean/luci-app-wrtbwmon/root/usr/sbin/wrtbwmon b/package/lean/luci-app-wrtbwmon/root/usr/sbin/wrtbwmon deleted file mode 100755 index b2c0b9a07a..0000000000 --- a/package/lean/luci-app-wrtbwmon/root/usr/sbin/wrtbwmon +++ /dev/null @@ -1,301 +0,0 @@ -#!/bin/sh -# -# wrtbwmon: traffic logging tool for routers -# -# Peter Bailey (peter.eldridge.bailey+wrtbwmon AT gmail.com) -# -# Based on work by: -# Emmanuel Brucy (e.brucy AT qut.edu.au) -# Fredrik Erlandsson (erlis AT linux.nu) -# twist - http://wiki.openwrt.org/RrdTrafficWatch - -trap "rm -f /tmp/*_$$.tmp; kill $$" INT -binDir=/usr/sbin -dataDir=/usr/share/wrtbwmon -lockDir=/tmp/wrtbwmon.lock -pidFile=$lockDir/pid -networkFuncs=/lib/functions/network.sh -uci=`which uci 2>/dev/null` -nslookup=`which nslookup 2>/dev/null` -nvram=`which nvram 2>/dev/null` - -chains='INPUT OUTPUT FORWARD' -DEBUG= -interfaces='eth0 tun0' # in addition to detected WAN -DB=$2 -mode= - -# DNS server for reverse lookups provided in "DNS". -# don't perform reverse DNS lookups by default -DO_RDNS=${DNS-} - -header="#mac,ip,iface,in,out,total,first_date,last_date" - -createDbIfMissing() -{ - [ ! -f "$DB" ] && echo $header > "$DB" -} - -checkDbArg() -{ - [ -z "$DB" ] && echo "ERROR: Missing argument 2 (database file)" && exit 1 -} - -checkDB() -{ - [ ! -f "$DB" ] && echo "ERROR: $DB does not exist" && exit 1 - [ ! -w "$DB" ] && echo "ERROR: $DB is not writable" && exit 1 -} - -checkWAN() -{ - [ -z "$wan" ] && echo "Warning: failed to detect WAN interface." -} - -lookup() -{ - MAC=$1 - IP=$2 - userDB=$3 - for USERSFILE in $userDB /tmp/dhcp.leases /tmp/dnsmasq.conf /etc/dnsmasq.conf /etc/hosts; do - [ -e "$USERSFILE" ] || continue - case $USERSFILE in - /tmp/dhcp.leases ) - USER=$(grep -i "$MAC" $USERSFILE | cut -f4 -s -d' ') - ;; - /etc/hosts ) - USER=$(grep "^$IP " $USERSFILE | cut -f2 -s -d' ') - ;; - * ) - USER=$(grep -i "$MAC" "$USERSFILE" | cut -f2 -s -d,) - ;; - esac - [ "$USER" = "*" ] && USER= - [ -n "$USER" ] && break - done - if [ -n "$DO_RDNS" -a -z "$USER" -a "$IP" != "NA" -a -n "$nslookup" ]; then - USER=`$nslookup $IP $DNS | awk '!/server can/{if($4){print $4; exit}}' | sed -re 's/[.]$//'` - fi - [ -z "$USER" ] && USER=${MAC} - echo $USER -} - -detectIF() -{ - if [ -f "$networkFuncs" ]; then - IF=`. $networkFuncs; network_get_device netdev $1; echo $netdev` - [ -n "$IF" ] && echo $IF && return - fi - - if [ -n "$uci" -a -x "$uci" ]; then - IF=`$uci get network.${1}.ifname 2>/dev/null` - [ $? -eq 0 -a -n "$IF" ] && echo $IF && return - fi - - if [ -n "$nvram" -a -x "$nvram" ]; then - IF=`$nvram get ${1}_ifname 2>/dev/null` - [ $? -eq 0 -a -n "$IF" ] && echo $IF && return - fi -} - -detectLAN() -{ - [ -e /sys/class/net/br-lan ] && echo br-lan && return - lan=$(detectIF lan) - [ -n "$lan" ] && echo $lan && return -} - -detectWAN() -{ - [ -n "$WAN_IF" ] && echo $WAN_IF && return - wan=$(detectIF wan) - [ -n "$wan" ] && echo $wan && return - wan=$(ip route show 2>/dev/null | grep default | sed -re '/^default/ s/default.*dev +([^ ]+).*/\1/') - [ -n "$wan" ] && echo $wan && return - [ -f "$networkFuncs" ] && wan=$(. $networkFuncs; network_find_wan wan; echo $wan) - [ -n "$wan" ] && echo $wan && return -} - -lock() -{ - attempts=0 - while [ $attempts -lt 10 ]; do - mkdir $lockDir 2>/dev/null && break - attempts=$((attempts+1)) - pid=`cat $pidFile 2>/dev/null` - if [ -n "$pid" ]; then - if [ -d "/proc/$pid" ]; then - [ -n "$DEBUG" ] && echo "WARNING: Lockfile detected but process $(cat $pidFile) does not exist !" - rm -rf $lockDir - else - sleep 1 - fi - fi - done - mkdir $lockDir 2>/dev/null - echo $$ > $pidFile - [ -n "$DEBUG" ] && echo $$ "got lock after $attempts attempts" - trap '' INT -} - -unlock() -{ - rm -rf $lockDir - [ -n "$DEBUG" ] && echo $$ "released lock" - trap "rm -f /tmp/*_$$.tmp; kill $$" INT -} - -# chain -newChain() -{ - chain=$1 - # Create the RRDIPT_$chain chain (it doesn't matter if it already exists). - iptables -t mangle -N RRDIPT_$chain 2> /dev/null - - # Add the RRDIPT_$chain CHAIN to the $chain chain if not present - iptables -t mangle -C $chain -j RRDIPT_$chain 2>/dev/null - if [ $? -ne 0 ]; then - [ -n "$DEBUG" ] && echo "DEBUG: iptables chain misplaced, recreating it..." - iptables -t mangle -I $chain -j RRDIPT_$chain - fi -} - -# chain tun -newRuleIF() -{ - chain=$1 - IF=$2 - - #!@todo test - if [ "$chain" = "OUTPUT" ]; then - cmd="iptables -t mangle -o $IF -j RETURN" - eval $cmd " -C RRDIPT_$chain 2>/dev/null" || eval $cmd " -A RRDIPT_$chain" - elif [ "$chain" = "INPUT" ]; then - cmd="iptables -t mangle -i $IF -j RETURN" - eval $cmd " -C RRDIPT_$chain 2>/dev/null" || eval $cmd " -A RRDIPT_$chain" - fi -} - -update() -{ - #!@todo could let readDB.awk handle this; that would place header - #!info in fewer places - createDbIfMissing - - checkDB - checkWAN - - > /tmp/iptables_$$.tmp - lock - # only zero our own chains - for chain in $chains; do - iptables -nvxL RRDIPT_$chain -t mangle -Z >> /tmp/iptables_$$.tmp - done - # the iptables and readDB commands have to be separate. Otherwise, - # they will fight over iptables locks - awk -v mode="$mode" -v interfaces=\""$interfaces"\" -f $binDir/readDB.awk \ - $DB \ - /proc/net/arp \ - /tmp/iptables_$$.tmp - unlock -} - -############################################################ - -case $1 in - "dump" ) - checkDbArg - lock - tr ',' '\t' < "$DB" - unlock - ;; - - "update" ) - checkDbArg - wan=$(detectWAN) - interfaces="$interfaces $wan" - update - rm -f /tmp/*_$$.tmp - exit - ;; - - "publish" ) - checkDbArg - [ -z "$3" ] && echo "ERROR: Missing argument 3 (output html file)" && exit 1 - - # sort DB - lock - - # busybox sort truncates numbers to 32 bits - grep -v '^#' $DB | awk -F, '{OFS=","; a=sprintf("%f",$4/1e6); $4=""; print a,$0}' | tr -s ',' | sort -rn | awk -F, '{OFS=",";$1=sprintf("%f",$1*1e6);print}' > /tmp/sorted_$$.tmp - - # create HTML page - rm -f $3.tmp - cp $dataDir/usage.htm1 $3.tmp - - #!@todo fix publishing - while IFS=, read PEAKUSAGE_IN MAC IP IFACE PEAKUSAGE_OUT TOTAL FIRSTSEEN LASTSEEN - do - echo " -new Array(\"$(lookup $MAC $IP $4)\",\"$MAC\",\"$IP\", -$PEAKUSAGE_IN,$PEAKUSAGE_OUT,$TOTAL,\"$FIRSTSEEN\",\"$LASTSEEN\")," >> $3.tmp - done < /tmp/sorted_$$.tmp - echo "0);" >> $3.tmp - - sed "s/(date)/`date`/" < $dataDir/usage.htm2 >> $3.tmp - mv $3.tmp $3 - - unlock - - #Free some memory - rm -f /tmp/*_$$.tmp - ;; - - "setup" ) - checkDbArg - [ -w "$DB" ] && echo "Warning: using existing $DB" - createDbIfMissing - - for chain in $chains; do - newChain $chain - done - - #lan=$(detectLAN) - wan=$(detectWAN) - checkWAN - interfaces="$interfaces $wan" - - # track local data - for chain in INPUT OUTPUT; do - for interface in $interfaces; do - [ -n "$interface" ] && [ -e "/sys/class/net/$interface" ] && newRuleIF $chain $interface - done - done - - # this will add rules for hosts in arp table - update - - rm -f /tmp/*_$$.tmp - ;; - - "remove" ) - iptables-save | grep -v RRDIPT | iptables-restore - rm -rf "$lockDir" - ;; - - *) - echo \ -"Usage: $0 {setup|update|publish|remove} [options...] -Options: - $0 setup database_file - $0 update database_file - $0 publish database_file path_of_html_report [user_file] -Examples: - $0 setup /tmp/usage.db - $0 update /tmp/usage.db - $0 publish /tmp/usage.db /www/user/usage.htm /jffs/users.txt - $0 remove -Note: [user_file] is an optional file to match users with MAC addresses. - Its format is \"00:MA:CA:DD:RE:SS,username\", with one entry per line." - ;; -esac diff --git a/package/lean/luci-app-wrtbwmon/root/usr/share/wrtbwmon/usage.htm1 b/package/lean/luci-app-wrtbwmon/root/usr/share/wrtbwmon/usage.htm1 deleted file mode 100644 index 1f0c342a7c..0000000000 --- a/package/lean/luci-app-wrtbwmon/root/usr/share/wrtbwmon/usage.htm1 +++ /dev/null @@ -1,23 +0,0 @@ -Traffic - -

Total Usage:

- - - - - - - - - -
UserDownloadUploadTotalFirst seenLast seen
-
This page was generated on (date) - From 9109439c3704a7da686757658073c7d9d097945f Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Thu, 18 Feb 2021 20:17:12 +0800 Subject: [PATCH 4/8] luci-app-wrtbwmon: update Copyright info Signed-off-by: CN_SZTL --- package/ctcgfw/luci-app-wrtbwmon/Makefile | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/package/ctcgfw/luci-app-wrtbwmon/Makefile b/package/ctcgfw/luci-app-wrtbwmon/Makefile index 89f52c9f83..4f6f2cec83 100644 --- a/package/ctcgfw/luci-app-wrtbwmon/Makefile +++ b/package/ctcgfw/luci-app-wrtbwmon/Makefile @@ -1,8 +1,7 @@ # -# Copyright (C) 2021 ImmortalWrt -# (https://project-openwrt.eu.org) +# Copyright (C) 2021 Van Waholtz # -# This is free software, licensed under the GNU General Public License v3. +# This is free software, licensed under the Apache License, Version 2.0. # See /LICENSE for more information. # From 06531db685d4467714be2c683d2600f80d778644 Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Thu, 18 Feb 2021 22:52:38 +0800 Subject: [PATCH 5/8] naiveproxy: backport patch to fix building on OpenWrt x86 platform Signed-off-by: CN_SZTL --- package/ctcgfw/naiveproxy/Makefile | 2 +- .../patches/010-Fix-OpenWrt-x86-builds.patch | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 package/ctcgfw/naiveproxy/patches/010-Fix-OpenWrt-x86-builds.patch diff --git a/package/ctcgfw/naiveproxy/Makefile b/package/ctcgfw/naiveproxy/Makefile index 8988bd288e..6a91c43604 100644 --- a/package/ctcgfw/naiveproxy/Makefile +++ b/package/ctcgfw/naiveproxy/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=naiveproxy PKG_VERSION:=88.0.4324.96-1 -PKG_RELEASE:=1 +PKG_RELEASE:=2 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=https://codeload.github.com/klzgrad/naiveproxy/tar.gz/v$(PKG_VERSION)? diff --git a/package/ctcgfw/naiveproxy/patches/010-Fix-OpenWrt-x86-builds.patch b/package/ctcgfw/naiveproxy/patches/010-Fix-OpenWrt-x86-builds.patch new file mode 100644 index 0000000000..ab85c7b063 --- /dev/null +++ b/package/ctcgfw/naiveproxy/patches/010-Fix-OpenWrt-x86-builds.patch @@ -0,0 +1,22 @@ +From 63f89cd454bcd1f2cdd14e63de0587a2f692cd07 Mon Sep 17 00:00:00 2001 +From: klzgrad +Date: Sun, 31 Jan 2021 20:15:28 +0800 +Subject: [PATCH] Fix OpenWrt x86 builds + +--- + src/build/toolchain/linux/BUILD.gn | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +--- a/src/build/toolchain/linux/BUILD.gn ++++ b/src/build/toolchain/linux/BUILD.gn +@@ -99,8 +99,8 @@ clang_toolchain("clang_x86") { + clang_toolchain("clang_x86_openwrt") { + # Output linker map files for binary size analysis. + enable_linker_map = true +- extra_cppflags = "--target=i386-openwrt-linux-musl -D_LIBCPP_HAS_MUSL_LIBC -D__UCLIBC__" +- extra_ldflags = "--target=i386-openwrt-linux-musl" ++ extra_cppflags = "--target=i486-openwrt-linux-musl -D_LIBCPP_HAS_MUSL_LIBC -D__UCLIBC__" ++ extra_ldflags = "--target=i486-openwrt-linux-musl" + + toolchain_args = { + current_cpu = "x86" From e99269f8fb2109952e7ee22ec1c3e645a862062d Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Fri, 19 Feb 2021 00:12:54 +0800 Subject: [PATCH 6/8] tinyfecVPN: switch git source As github tarball doesn't include the files of submodules, so switch to git source to fetch them. Signed-off-by: CN_SZTL --- package/ctcgfw/tinyfecvpn/Makefile | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/package/ctcgfw/tinyfecvpn/Makefile b/package/ctcgfw/tinyfecvpn/Makefile index 2c2ac43918..daa5aebd23 100644 --- a/package/ctcgfw/tinyfecvpn/Makefile +++ b/package/ctcgfw/tinyfecvpn/Makefile @@ -9,11 +9,13 @@ include $(TOPDIR)/rules.mk PKG_NAME:=tinyfecVPN PKG_VERSION:=20210116.0 -PKG_RELEASE:=1 +PKG_RELEASE:=2 -PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz -PKG_SOURCE_URL:=https://codeload.github.com/wangyu-/tinyfecVPN/tar.gz/$(PKG_VERSION)? -PKG_HASH:=4e7494dcee9398a51497689c319bea7184152780fc06a2e05b6f9c16a6a9ea6e +PKG_SOURCE_PROTO:=git +PKG_SOURCE_URL:=https://github.com/wangyu-/tinyfecVPN.git +PKG_SOURCE_DATE:=2021-01-17 +PKG_SOURCE_VERSION:=c9b98721ea1d62ab8e1c4c9e2a0ed04394dfe0ae +PKG_MIRROR_HASH:=28cdadf0f162e52d3c6b10b6a6cdcd22e80783b36b33e341b5dea156bfb75b74 PKG_LICENSE:=MIT PKG_MAINTAINER:=Yu Wang @@ -22,7 +24,7 @@ PKG_BUILD_PARALLEL:=1 include $(INCLUDE_DIR)/package.mk -define Package/tinyfecVPN +define Package/tinyfecvpn SECTION:=net CATEGORY:=Network SUBMENU:=VPN @@ -31,7 +33,7 @@ define Package/tinyfecVPN DEPENDS:=+libpthread +libstdcpp +kmod-tun endef -define Package/tinyfecVPN/description +define Package/tinyfecvpn/description A Lightweight VPN with Build-in Forward Error Correction Support (or A Network Improving Tool which works at VPN mode). Improves your Network Quality on a High-latency Lossy Link. endef @@ -41,12 +43,14 @@ MAKE_FLAGS += cross define Build/Configure sed -i 's/cc_cross=.*/cc_cross=$(TARGET_CXX)/g' $(PKG_BUILD_DIR)/makefile sed -i '/\*gitversion/d' $(PKG_BUILD_DIR)/makefile - echo 'const char *gitversion = "$(PKG_VERSION)";' > $(PKG_BUILD_DIR)/git_version.h + echo 'const char *gitversion = "$(PKG_SOURCE_VERSION)";' > $(PKG_BUILD_DIR)/git_version.h + + $(call Build/Configure/Default) endef -define Package/tinyfecVPN/install +define Package/tinyfecvpn/install $(INSTALL_DIR) $(1)/usr/bin $(INSTALL_BIN) $(PKG_BUILD_DIR)/tinyvpn_cross $(1)/usr/bin/tinyvpn endef -$(eval $(call BuildPackage,tinyfecVPN)) +$(eval $(call BuildPackage,tinyfecvpn)) From e171b967a686294b206c3603cb45328212657b60 Mon Sep 17 00:00:00 2001 From: CN_SZTL Date: Fri, 19 Feb 2021 03:25:43 +0800 Subject: [PATCH 7/8] Revert "package: libs: ncurses/readline use PKG_ABI_VERSION" This reverts commit f2ee0fb37683ca18ed33d2b0031e539363030ea2. Signed-off-by: CN_SZTL --- package/libs/ncurses/Makefile | 4 ++-- package/libs/readline/Makefile | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/package/libs/ncurses/Makefile b/package/libs/ncurses/Makefile index c72732daee..cc1e960a0c 100644 --- a/package/libs/ncurses/Makefile +++ b/package/libs/ncurses/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=ncurses PKG_VERSION:=6.2 -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@GNU/$(PKG_NAME) @@ -40,7 +40,7 @@ define Package/libncurses URL:=http://www.gnu.org/software/ncurses/ PROVIDES:=libncursesw DEPENDS:= +terminfo - ABI_VERSION:=$(PKG_ABI_VERSION) + ABI_VERSION:=6 endef define Package/libncurses-dev diff --git a/package/libs/readline/Makefile b/package/libs/readline/Makefile index 11933273b6..d41a6d74f4 100644 --- a/package/libs/readline/Makefile +++ b/package/libs/readline/Makefile @@ -9,7 +9,7 @@ include $(TOPDIR)/rules.mk PKG_NAME:=readline PKG_VERSION:=8.1 -PKG_RELEASE:=2 +PKG_RELEASE:=1 PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:=@GNU/readline @@ -33,7 +33,7 @@ define Package/libreadline TITLE:=Command lines edition library DEPENDS:=+libncursesw URL:=http://cnswww.cns.cwru.edu/php/chet/readline/rltop.html - ABI_VERSION:=$(PKG_ABI_VERSION) + ABI_VERSION:=8 endef define Package/libreadline/description From 2f46ef4d87307eea7156705742b7f936cd5b791c Mon Sep 17 00:00:00 2001 From: Felix Fietkau Date: Thu, 18 Feb 2021 19:51:05 +0100 Subject: [PATCH 8/8] build: fix ABI version for PROVIDES symbols GetABISuffix does not work for intra-package ABI version of provided symbols, since ABIV_$(provided) is not set. Fix ABI version by using $(ABIV_$(1)) directly Signed-off-by: Felix Fietkau Signed-off-by: CN_SZTL --- include/package-ipkg.mk | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/package-ipkg.mk b/include/package-ipkg.mk index a8210f8e31..5e51b301e1 100644 --- a/include/package-ipkg.mk +++ b/include/package-ipkg.mk @@ -175,7 +175,7 @@ Package: $(1)$$(ABIV_$(1)) Version: $(VERSION) $$(call addfield,Depends,$$(Package/$(1)/DEPENDS) )$$(call addfield,Conflicts,$$(call mergelist,$(CONFLICTS)) -)$$(call addfield,Provides,$$(call mergelist,$$(filter-out $(1)$$(ABIV_$(1)),$(PROVIDES)$$(if $$(ABIV_$(1)), $(1) $(foreach provide,$(PROVIDES),$(provide)$$(call GetABISuffix,$(provide)))))) +)$$(call addfield,Provides,$$(call mergelist,$$(filter-out $(1)$$(ABIV_$(1)),$(PROVIDES)$$(if $$(ABIV_$(1)), $(1) $(foreach provide,$(PROVIDES),$(provide)$$(ABIV_$(1)))))) )$$(call addfield,Alternatives,$$(call mergelist,$(ALTERNATIVES)) )$$(call addfield,Source,$(SOURCE) )$$(call addfield,SourceName,$(1)