diff --git a/CONTRIBUTED.md b/CONTRIBUTED.md index 1a4b614ddf..b445987448 100644 --- a/CONTRIBUTED.md +++ b/CONTRIBUTED.md @@ -61,9 +61,7 @@ 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).
-wrtbwmon source: [brvphoenix/wrtbwmon](https://github.com/brvphoenix/wrtbwmon).
-luci-app-wrtbwmon source: [brvphoenix/luci-app-wrtbwmon](https://github.com/brvphoenix/luci-app-wrtbwmon). +luci-proto-minieap source: [ysc3839/luci-proto-minieap](https://github.com/ysc3839/luci-proto-minieap). ## License ### Depend on their own License. diff --git a/include/toplevel.mk b/include/toplevel.mk index 48ea44aa24..f5a2593a10 100644 --- a/include/toplevel.mk +++ b/include/toplevel.mk @@ -258,7 +258,7 @@ help: cat README.md distclean: - rm -rf bin build_dir .ccache .config* dl feeds key-build* logs package/feeds package/openwrt-packages staging_dir tmp + rm -rf bin build_dir .ccache .config* dl feeds key-build* logs package/feeds staging_dir tmp @$(_SINGLE)$(SUBMAKE) -C scripts/config clean ifeq ($(findstring v,$(DEBUG)),) diff --git a/include/version.mk b/include/version.mk index 510a7a411c..e1d92cc8b1 100644 --- a/include/version.mk +++ b/include/version.mk @@ -23,7 +23,7 @@ PKG_CONFIG_DEPENDS += \ sanitize = $(call tolower,$(subst _,-,$(subst $(space),-,$(1)))) VERSION_NUMBER:=$(call qstrip,$(CONFIG_VERSION_NUMBER)) -VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),SNAPSHOT) +VERSION_NUMBER:=$(if $(VERSION_NUMBER),$(VERSION_NUMBER),18.06-SNAPSHOT) VERSION_CODE:=$(call qstrip,$(CONFIG_VERSION_CODE)) VERSION_CODE:=$(if $(VERSION_CODE),$(VERSION_CODE),$(REVISION)) diff --git a/package/ctcgfw/luci-app-wrtbwmon/Makefile b/package/ctcgfw/luci-app-wrtbwmon/Makefile deleted file mode 100644 index 4f6f2cec83..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/Makefile +++ /dev/null @@ -1,23 +0,0 @@ -# -# Copyright (C) 2021 Van Waholtz -# -# This is free software, licensed under the Apache License, Version 2.0. -# 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 deleted file mode 100644 index da9470a111..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/etc/config/wrtbwmon +++ /dev/null @@ -1,5 +0,0 @@ - -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 deleted file mode 100755 index 41b49a4a20..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/etc/hotplug.d/iface/99-wrtbwmon +++ /dev/null @@ -1,9 +0,0 @@ -#!/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 deleted file mode 100755 index 1c3213ee17..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/etc/init.d/wrtbwmon +++ /dev/null @@ -1,44 +0,0 @@ -#!/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 deleted file mode 100644 index 20f254cae6..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua +++ /dev/null @@ -1,20 +0,0 @@ -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 deleted file mode 100644 index 6b3555e451..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua +++ /dev/null @@ -1,48 +0,0 @@ -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/ctcgfw/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm b/package/ctcgfw/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm deleted file mode 100644 index b78e0e86fc..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm +++ /dev/null @@ -1,579 +0,0 @@ -<%# - 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 deleted file mode 100644 index 02033745c8..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po +++ /dev/null @@ -1,152 +0,0 @@ -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 deleted file mode 100755 index 97ada9bccd..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon +++ /dev/null @@ -1,11 +0,0 @@ -#!/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 deleted file mode 100755 index 2080fe5f79..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/readDB.awk +++ /dev/null @@ -1,213 +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=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 deleted file mode 100755 index 91089a1eee..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/usr/sbin/wrtbwmon +++ /dev/null @@ -1,460 +0,0 @@ -#!/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 deleted file mode 100644 index c469cb7d91..0000000000 --- a/package/ctcgfw/luci-app-wrtbwmon/usr/share/wrtbwmon/usage.htm1 +++ /dev/null @@ -1,34 +0,0 @@ -Traffic - -

Total Usage:

- - - - - - - - - - - -
UserDown SpeedUp SpeedDownloadUploadTotalFirst seenLast seen
-
This page was generated on (date) - diff --git a/package/ctcgfw/xray-plugin/Makefile b/package/ctcgfw/xray-plugin/Makefile new file mode 100644 index 0000000000..07e870eef2 --- /dev/null +++ b/package/ctcgfw/xray-plugin/Makefile @@ -0,0 +1,84 @@ +# +# Copyright (C) 2021 ImmortalWrt +# +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=xray-plugin +PKG_VERSION:=1.3.0 +PKG_RELEASE:=1 + +PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz +PKG_SOURCE_URL:=https://codeload.github.com/teddysun/xray-plugin/tar.gz/v$(PKG_VERSION)? +PKG_HASH:=a74adb1ea36819b634fb2b09fc2ac14ec2c57488285c82e6e26f1347de1d6324 + +PKG_LICENSE:=MIT +PKG_LICENSE_FILES:=LICENSE +PKG_MAINTAINER:=Tianling Shen + +PKG_CONFIG_DEPENDS:= \ + CONFIG_XRAY_PLUGIN_PROVIDE_V2RAY_PLUGIN \ + CONFIG_XRAY_PLUGIN_COMPRESS_GOPROXY \ + CONFIG_XRAY_PLUGIN_COMPRESS_UPX + +PKG_BUILD_DEPENDS:=golang/host +PKG_BUILD_PARALLEL:=1 +PKG_USE_MIPS16:=0 + +GO_PKG:=github.com/teddysun/xray-plugin +GO_PKG_LDFLAGS:=-s -w + +include $(INCLUDE_DIR)/package.mk +include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk + +define Package/xray-plugin/config +config XRAY_PLUGIN_PROVIDE_V2RAY_PLUGIN + bool "Provide v2ray-plugin binary using xray-plugin" + default n + +config XRAY_PLUGIN_COMPRESS_GOPROXY + bool "Compiling with GOPROXY proxy" + default n + +config XRAY_PLUGIN_COMPRESS_UPX + bool "Compress executable files with UPX" + default y +endef + +ifneq ($(CONFIG_XRAY_PLUGIN_COMPRESS_GOPROXY),) + export GO111MODULE=on + export GOPROXY=https://goproxy.io +endif + +define Package/xray-plugin + SECTION:=net + CATEGORY:=Network + TITLE:=SIP003 plugin for Shadowsocks, based on Xray + URL:=https://github.com/teddysun/xray-plugin + DEPENDS:=$(GO_ARCH_DEPENDS) +ca-bundle +endef + +define Package/xray-plugin/description + Yet another SIP003 plugin for Shadowsocks, based on Xray. +endef + +define Build/Compile + $(call GoPackage/Build/Compile) +ifneq ($(CONFIG_XRAY_PLUGIN_COMPRESS_UPX),) + $(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/xray-plugin +endif +endef + +define Package/xray-plugin/install + $(call GoPackage/Package/Install/Bin,$(1)) +ifneq ($(CONFIG_XRAY_PLUGIN_PROVIDE_V2RAY_PLUGIN),) + $(LN) xray-plugin $(1)/usr/bin/v2ray-plugin +endif +endef + +$(eval $(call GoBinPackage,xray-plugin)) +$(eval $(call BuildPackage,xray-plugin)) diff --git a/package/lean/autocore/files/arm/index.htm b/package/lean/autocore/files/arm/index.htm index bfca2f428c..2c7225d423 100644 --- a/package/lean/autocore/files/arm/index.htm +++ b/package/lean/autocore/files/arm/index.htm @@ -49,7 +49,7 @@ local user_info = luci.sys.exec("cat /proc/net/arp | grep 'br-lan' | grep '0x2' | wc -l") - local cpu_usage = (luci.sys.exec("expr 100 - $(top -n 1 | grep 'CPU:' | awk -F '%' '{print$4}' | awk -F ' ' '{print$2}')") or "6") .. "%" + local cpu_usage = luci.sys.exec("top -n1 | awk '/^CPU/ {printf(\"%d%%\", 100 - $8)}'") or "6%" local cpu_info = luci.sys.exec("/sbin/cpuinfo") or "ARM Processor" local rv = { diff --git a/package/lean/autocore/files/arm/sbin/cpuinfo b/package/lean/autocore/files/arm/sbin/cpuinfo index c2a24dacdb..c660d3fafd 100755 --- a/package/lean/autocore/files/arm/sbin/cpuinfo +++ b/package/lean/autocore/files/arm/sbin/cpuinfo @@ -21,7 +21,7 @@ if grep -q "bcm27xx" "/etc/openwrt_release"; then cpu_temp="$(vcgencmd measure_temp | awk -F '=' '{print $2}' | awk -F "'" '{print $1}')°C" else [ -e "/sys/class/thermal/thermal_zone0/temp" ] && \ - cpu_temp="$(awk "BEGIN{printf (\"%.1f\n\",$(cat "/sys/class/thermal/thermal_zone0/temp")/1000)}")°C" + cpu_temp="$(awk '{printf("%.1f°C", $0 / 1000)}' /sys/class/thermal/thermal_zone0/temp)" fi if [ -z "${cpu_freq}" ] && [ -z "${cpu_temp}" ]; then diff --git a/package/lean/autocore/files/x86/index.htm b/package/lean/autocore/files/x86/index.htm index c24224cb39..ca8d349776 100644 --- a/package/lean/autocore/files/x86/index.htm +++ b/package/lean/autocore/files/x86/index.htm @@ -52,7 +52,7 @@ local user_info = luci.sys.exec("cat /proc/net/arp | grep '0x2' | wc -l") or 0 - local cpu_usage = (luci.sys.exec("expr 100 - $(top -n 1 | grep 'CPU:' | awk -F '%' '{print$4}' | awk -F ' ' '{print$2}')") or "6") .. "%" + local cpu_usage = luci.sys.exec("top -n1 | awk '/^CPU/ {printf(\"%d%%\", 100 - $8)}'") or "6%" local rv = { cpuusage = cpu_usage, diff --git a/package/lean/ddns-scripts_dnspod/update_dnspod_cn.sh b/package/lean/ddns-scripts_dnspod/update_dnspod_cn.sh index 493536527a..ff1df9f8d3 100644 --- a/package/lean/ddns-scripts_dnspod/update_dnspod_cn.sh +++ b/package/lean/ddns-scripts_dnspod/update_dnspod_cn.sh @@ -5,7 +5,7 @@ [ -z "$password" ] && write_log 14 "Configuration error! [Password] cannot be empty" #检查外部调用工具 -[ -n "$WGET_SSL" ] || write_log 13 "GNU Wget support is required to use Alibaba Cloud API. Please install first" +[ -n "$WGET_SSL" ] || write_log 13 "GNU Wget support is required to use dnspod API. Please install first" # 变量声明 local __URLBASE __HOST __DOMAIN __TYPE __CMDBASE __POST __POST1 __RECIP __RECID __value __TTL @@ -114,7 +114,7 @@ update_domain() { #获取域名解析记录 describe_domain() { ret=0 - __POST="login_token=$username,$password&format=json&domain=$__DOMAIN&sub_domain=$__HOST" + __POST="login_token=$username,$password&format=json&domain=$__DOMAIN&sub_domain=$__HOST&record_type=$__TYPE" __POST1="$__POST&value=$__IP&record_type=$__TYPE&record_line_id=0" dnspod_transfer 0 __TMP=`jsonfilter -i $DATFILE -e "@.records[@.type!='NS']"` diff --git a/package/lean/luci-app-wrtbwmon/Makefile b/package/lean/luci-app-wrtbwmon/Makefile new file mode 100644 index 0000000000..412b35fe52 --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/Makefile @@ -0,0 +1,17 @@ +# 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 new file mode 100644 index 0000000000..36812e723b --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/htdocs/luci-static/wrtbwmon.js @@ -0,0 +1,562 @@ +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 new file mode 100644 index 0000000000..25909c846d --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/luasrc/controller/wrtbwmon.lua @@ -0,0 +1,43 @@ +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 new file mode 100644 index 0000000000..469d4f8f2c --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/config.lua @@ -0,0 +1,18 @@ +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/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua b/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua similarity index 69% rename from package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua rename to package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua index 46baa33127..671879b4cc 100644 --- a/package/ctcgfw/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua +++ b/package/lean/luci-app-wrtbwmon/luasrc/model/cbi/wrtbwmon/custom.lua @@ -1,11 +1,10 @@ -local USER_FILE_PATH = "/etc/wrtbwmon.user" +local USER_FILE_PATH = "/etc/config/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. " - .. "Each line must have the following format: \"00:aa:bb:cc:ee:ff,username\".")) + 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")) local o = f:field(Value, "_custom") @@ -21,6 +20,4 @@ function o.write(self, section, value) fs.writefile(USER_FILE_PATH, value) end -f.submit = translate("Submit") - return f diff --git a/package/lean/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm b/package/lean/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm new file mode 100644 index 0000000000..68713b1238 --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/luasrc/view/wrtbwmon.htm @@ -0,0 +1,46 @@ +<%+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 new file mode 100644 index 0000000000..3eb050e3f4 --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/po/zh-cn/wrtbwmon.po @@ -0,0 +1,56 @@ +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 new file mode 100644 index 0000000000..419270dbab --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/root/etc/config/wrtbwmon @@ -0,0 +1,4 @@ + +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 new file mode 100755 index 0000000000..d57c09ae1d --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/root/etc/init.d/wrtbwmon @@ -0,0 +1,22 @@ +#!/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 new file mode 100755 index 0000000000..bcb5b337f3 --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/root/etc/uci-defaults/luci-wrtbwmon @@ -0,0 +1,14 @@ +#!/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 new file mode 100755 index 0000000000..39bcf43a10 --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/root/etc/wrtbwmon.include @@ -0,0 +1 @@ +/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 new file mode 100755 index 0000000000..fe67e4ae8b --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/root/usr/sbin/readDB.awk @@ -0,0 +1,157 @@ +#!/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 new file mode 100755 index 0000000000..b2c0b9a07a --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/root/usr/sbin/wrtbwmon @@ -0,0 +1,301 @@ +#!/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 new file mode 100644 index 0000000000..1f0c342a7c --- /dev/null +++ b/package/lean/luci-app-wrtbwmon/root/usr/share/wrtbwmon/usage.htm1 @@ -0,0 +1,23 @@ +Traffic + +

Total Usage:

+ + + + + + + + + +
UserDownloadUploadTotalFirst seenLast seen
+
This page was generated on (date) + diff --git a/package/libs/openssl/Makefile b/package/libs/openssl/Makefile index 9041bfec36..24fd09a7b5 100644 --- a/package/libs/openssl/Makefile +++ b/package/libs/openssl/Makefile @@ -21,10 +21,13 @@ PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz PKG_SOURCE_URL:= \ https://mirrors.cloud.tencent.com/openssl/source/ \ https://mirrors.cloud.tencent.com/openssl/source/old/$(PKG_BASE)/ \ - https://ftp.fi.muni.cz/pub/openssl/source/ \ - ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/ \ https://www.openssl.org/source/ \ - https://www.openssl.org/source/old/$(PKG_BASE)/ + https://www.openssl.org/source/old/$(PKG_BASE)/ \ + https://ftp.fi.muni.cz/pub/openssl/source/ \ + https://ftp.fi.muni.cz/pub/openssl/source/old/$(PKG_BASE)/ \ + ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/ \ + ftp://ftp.pca.dfn.de/pub/tools/net/openssl/source/old/$(PKG_BASE)/ + PKG_HASH:=aaf2fcb575cdf6491b98ab4829abf78a3dec8402b8b81efc8f23c00d443981bf PKG_LICENSE:=OpenSSL diff --git a/package/libs/wolfssl/Config.in b/package/libs/wolfssl/Config.in index c2f66589e6..5d1f119ac4 100644 --- a/package/libs/wolfssl/Config.in +++ b/package/libs/wolfssl/Config.in @@ -48,7 +48,7 @@ config WOLFSSL_HAS_WPAS default y config WOLFSSL_HAS_ECC25519 - bool "Include ECC Curve 22519 support" + bool "Include ECC Curve 25519 support" default n config WOLFSSL_HAS_DEVCRYPTO diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua index 3af06fd3b2..746a13f78e 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/api/gen_xray.lua @@ -96,10 +96,6 @@ function gen_outbound(node, tag, is_proxy) node.stream_security = "xtls" end end - - if node.transport == "mkcp" or node.transport == "quic" then - node.stream_security = "none" - end end result = { @@ -260,77 +256,12 @@ if node_section then if node.protocol == "_shunt" then local rules = {} - ucursor:foreach(appname, "shunt_rules", function(e) - local name = e[".name"] - local _node_id = node[name] or "nil" - local is_proxy = node[name .. "_proxy"] or "0" - local outboundTag - if _node_id == "_direct" then - outboundTag = "direct" - elseif _node_id == "_blackhole" then - outboundTag = "blackhole" - else - if _node_id ~= "nil" then - local has_outbound - for index, value in ipairs(outbounds) do - if value["_flag_tag"] == _node_id and value["_flag_is_proxy"] == is_proxy then - has_outbound = api.clone(value) - break - end - end - if has_outbound then - has_outbound["tag"] = name - table.insert(outbounds, has_outbound) - outboundTag = name - else - local _node = ucursor:get_all(appname, _node_id) - local _outbound = gen_outbound(_node, name, is_proxy) - if _outbound then - if is_proxy == "1" then - table.insert(rules, 1, { - type = "field", - inboundTag = {"proxy_" .. name}, - outboundTag = "default" - }) - end - table.insert(outbounds, _outbound) - outboundTag = name - end - end - end - end - if outboundTag then - if e.domain_list then - local _domain = {} - string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) - table.insert(_domain, w) - end) - table.insert(rules, { - type = "field", - outboundTag = outboundTag, - domain = _domain - }) - end - if e.ip_list then - local _ip = {} - string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) - table.insert(_ip, w) - end) - table.insert(rules, { - type = "field", - outboundTag = outboundTag, - ip = _ip - }) - end - end - end) - local default_node_id = node.default_node or "_direct" - local outboundTag + local default_outboundTag if default_node_id == "_direct" then - outboundTag = "direct" + default_outboundTag = "direct" elseif default_node_id == "_blackhole" then - outboundTag = "blackhole" + default_outboundTag = "blackhole" else local default_node = ucursor:get_all(appname, default_node_id) local main_node_id = node.main_node or "nil" @@ -365,13 +296,100 @@ if node_section then local default_outbound = gen_outbound(default_node, "default") if default_outbound then table.insert(outbounds, default_outbound) - outboundTag = "default" + default_outboundTag = "default" end end - if outboundTag then + + ucursor:foreach(appname, "shunt_rules", function(e) + local name = e[".name"] + local _node_id = node[name] or "nil" + local is_proxy = node[name .. "_proxy"] or "0" + local outboundTag + if _node_id == "_direct" then + outboundTag = "direct" + elseif _node_id == "_blackhole" then + outboundTag = "blackhole" + elseif _node_id == "_default" then + outboundTag = "default" + else + if _node_id ~= "nil" then + local has_outbound + for index, value in ipairs(outbounds) do + if value["_flag_tag"] == _node_id and value["_flag_is_proxy"] == is_proxy then + has_outbound = api.clone(value) + break + end + end + if has_outbound then + has_outbound["tag"] = name + table.insert(outbounds, has_outbound) + outboundTag = name + else + local _node = ucursor:get_all(appname, _node_id) + local _outbound = gen_outbound(_node, name, is_proxy) + if _outbound then + if is_proxy == "1" then + table.insert(rules, 1, { + type = "field", + inboundTag = {"proxy_" .. name}, + outboundTag = "default" + }) + end + table.insert(outbounds, _outbound) + outboundTag = name + end + end + end + end + if outboundTag then + if outboundTag == "default" then + outboundTag = default_outboundTag + end + local protocols = nil + if e["protocol"] and e["protocol"] ~= "" then + protocols = {} + string.gsub(e["protocol"], '[^' .. " " .. ']+', function(w) + table.insert(protocols, w) + end) + end + if e.domain_list then + local _domain = {} + string.gsub(e.domain_list, '[^' .. "\r\n" .. ']+', function(w) + table.insert(_domain, w) + end) + table.insert(rules, { + type = "field", + outboundTag = outboundTag, + domain = _domain, + protocol = protocols + }) + end + if e.ip_list then + local _ip = {} + string.gsub(e.ip_list, '[^' .. "\r\n" .. ']+', function(w) + table.insert(_ip, w) + end) + table.insert(rules, { + type = "field", + outboundTag = outboundTag, + ip = _ip, + protocol = protocols + }) + end + if not e.domain_list and not e.ip_list and protocols then + table.insert(rules, { + type = "field", + outboundTag = outboundTag, + protocol = protocols + }) + end + end + end) + + if default_outboundTag then table.insert(rules, { type = "field", - outboundTag = outboundTag, + outboundTag = default_outboundTag, network = network }) end 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 2cfab4bd10..23e3754980 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 @@ -120,7 +120,8 @@ if has_xray and #nodes_table > 0 then local id = e[".name"] o = s:taboption("Main", ListValue, v.id .. "." .. id .. "_node", string.format('* %s', api.url("shunt_rules", id), translate(e.remarks))) o:depends("tcp_node", v.id) - o:value("nil", translate("Default")) + o:value("nil", translate("Close")) + o:value("_default", translate("Default")) o:value("_direct", translate("Direct Connection")) o:value("_blackhole", translate("Blackhole")) for k1, v1 in pairs(normal_list) do @@ -174,26 +175,6 @@ udp_node:value("tcp_", translate("Same as the tcp node")) s:tab("DNS", translate("DNS")) -o = s:taboption("DNS", Value, "up_china_dns", translate("Local DNS") .. "(UDP)") -o.description = translate("IP:Port mode acceptable, multi value split with english comma.") .. "
" .. translate("When the selection is not the default, this DNS is forced to be set to dnsmasq upstream DNS.") -o.default = "default" -o:value("default", translate("Default")) -if has_xray then - o:value("xray_doh", "Xray DNS(DoH)") -end -o:value("223.5.5.5", "223.5.5.5 (" .. translate("Ali") .. "DNS)") -o:value("114.114.114.114", "114.114.114.114 (114DNS)") -o:value("119.29.29.29", "119.29.29.29 (DNSPOD DNS)") -o:value("180.76.76.76", "180.76.76.76 (" .. translate("Baidu") .. "DNS)") - ----- DoH -o = s:taboption("DNS", Value, "up_china_dns_doh", translate("DoH request address")) -o:value("https://dns.alidns.com/dns-query,223.5.5.5", "AliDNS") -o:value("https://doh.pub/dns-query,119.29.29.29", "DNSPod") -o.default = "https://dns.alidns.com/dns-query,223.5.5.5" -o.validate = doh_validate -o:depends("up_china_dns", "xray_doh") - ---- DNS Forward Mode o = s:taboption("DNS", ListValue, "dns_mode", translate("Filter Mode")) o.rmempty = false @@ -209,8 +190,8 @@ if has_xray then o:value("xray_doh", "Xray DNS(DoH)") end o:value("udp", translatef("Requery DNS By %s", translate("UDP Node"))) +o:value("custom", translate("Custom DNS") .. "(UDP)") o:value("nonuse", translate("No Filter")) -o:value("custom", translate("Custom DNS")) ---- Custom DNS o = s:taboption("DNS", Value, "custom_dns", translate("Custom DNS")) diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua index b8c933e995..783d9a6f33 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/node_config.lua @@ -129,7 +129,8 @@ balancing_node:depends("protocol", "_balancing") -- 分流 uci:foreach(appname, "shunt_rules", function(e) o = s:option(ListValue, e[".name"], string.format('* %s', api.url("shunt_rules", e[".name"]), translate(e.remarks))) - o:value("nil", translate("Default")) + o:value("nil", translate("Close")) + o:value("_default", translate("Default")) o:value("_direct", translate("Direct Connection")) o:value("_blackhole", translate("Blackhole")) o:depends("protocol", "_shunt") diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua index de2e63faa6..7d8bec44c9 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/rule.lua @@ -56,7 +56,7 @@ o = s:option(Value, "xray_location_asset", translate("Location of Xray asset"), o.default = "/usr/share/xray/" o.rmempty = false -s = m:section(TypedSection, "shunt_rules", "Xray" .. translate("Shunt") .. translate("Rule")) +s = m:section(TypedSection, "shunt_rules", "Xray" .. translate("Shunt") .. translate("Rule"), "" .. translate("Please note attention to the priority, the higher the order, the higher the priority.") .. "") s.template = "cbi/tblsection" s.anonymous = false s.addremove = true diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua index 94814bf8b9..d0976d4257 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/client/shunt_rules.lua @@ -12,6 +12,11 @@ remarks = s:option(Value, "remarks", translate("Remarks")) remarks.default = arg[1] remarks.rmempty = false +protocol = s:option(MultiValue, "protocol", translate("Protocol")) +protocol:value("http") +protocol:value("tls") +protocol:value("bittorrent") + domain_list = s:option(TextValue, "domain_list", translate("Domain")) domain_list.rows = 10 domain_list.wrap = "off" diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/xray.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/xray.lua index d5779e0be5..23226bf84e 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/xray.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/api/xray.lua @@ -15,7 +15,6 @@ function gen_config(user) clients[i] = { id = user.uuid[i], flow = ("1" == user.xtls) and user.flow or nil, - level = user.level and tonumber(user.level) or nil, alterId = user.alter_id and tonumber(user.alter_id) or nil } end @@ -50,7 +49,6 @@ function gen_config(user) settings = { method = user.method, password = user.password, - level = user.level and tonumber(user.level) or nil, network = user.ss_network or "TCP,UDP" } elseif user.protocol == "trojan" then @@ -60,7 +58,6 @@ function gen_config(user) clients[i] = { flow = ("1" == user.xtls) and user.flow or nil, password = user.uuid[i], - level = user.level and tonumber(user.level) or nil, } end settings = { @@ -71,7 +68,6 @@ function gen_config(user) settings = { users = { { - level = user.level and tonumber(user.level) or nil, secret = (user.password == nil) and "" or user.password } } @@ -115,9 +111,23 @@ function gen_config(user) } if user.transit_node and user.transit_node ~= "nil" then + local transit_node_t = ucic:get_all("passwall", user.transit_node) + if user.transit_node == "_socks" or user.transit_node == "_http" then + transit_node_t = { + type = "Xray", + protocol = user.transit_node:gsub("_", ""), + transport = "tcp", + address = user.transit_node_address, + port = user.transit_node_port, + username = (user.transit_node_username and user.transit_node_username ~= "") and user.transit_node_username or nil, + password = (user.transit_node_password and user.transit_node_password ~= "") and user.transit_node_password or nil, + } + end local gen_xray = require("luci.model.cbi.passwall.api.gen_xray") - local client = gen_xray.gen_outbound(ucic:get_all("passwall", user.transit_node), "transit") - table.insert(outbounds, 1, client) + local outbound = gen_xray.gen_outbound(transit_node_t, "transit") + if outbound then + table.insert(outbounds, 1, outbound) + end end local config = { @@ -216,10 +226,5 @@ function gen_config(user) end end - if user.transport == "mkcp" or user.transport == "quic" then - config.inbounds[1].streamSettings.security = "none" - config.inbounds[1].streamSettings.tlsSettings = nil - end - return config end diff --git a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua index 14fda9b01a..16e32e3a41 100644 --- a/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua +++ b/package/lienol/luci-app-passwall/luasrc/model/cbi/passwall/server/user.lua @@ -246,13 +246,6 @@ uuid:depends("type", "Trojan-Plus") alter_id = s:option(Value, "alter_id", translate("Alter ID")) alter_id:depends({ type = "Xray", protocol = "vmess" }) -level = s:option(Value, "level", translate("User Level")) -level:depends({ type = "Xray", protocol = "vmess" }) -level:depends({ type = "Xray", protocol = "vless" }) -level:depends({ type = "Xray", protocol = "shadowsocks" }) -level:depends({ type = "Xray", protocol = "trojan" }) -level:depends({ type = "Xray", protocol = "mtproto" }) - tls = s:option(Flag, "tls", translate("TLS")) tls.default = 0 tls.validate = function(self, value, t) @@ -565,10 +558,30 @@ end transit_node = s:option(ListValue, "transit_node", translate("transit node")) transit_node:value("nil", translate("Close")) +transit_node:value("_socks", translate("Custom Socks")) +transit_node:value("_http", translate("Custom HTTP")) for k, v in pairs(nodes_table) do transit_node:value(v.id, v.remarks) end transit_node.default = "nil" transit_node:depends("type", "Xray") +transit_node_address = s:option(Value, "transit_node_address", translate("Address (Support Domain Name)")) +transit_node_address:depends("transit_node", "_socks") +transit_node_address:depends("transit_node", "_http") + +transit_node_port = s:option(Value, "transit_node_port", translate("Port")) +transit_node_port.datatype = "port" +transit_node_port:depends("transit_node", "_socks") +transit_node_port:depends("transit_node", "_http") + +transit_node_username = s:option(Value, "transit_node_username", translate("Username")) +transit_node_username:depends("transit_node", "_socks") +transit_node_username:depends("transit_node", "_http") + +transit_node_password = s:option(Value, "transit_node_password", translate("Password")) +transit_node_password.password = true +transit_node_password:depends("transit_node", "_socks") +transit_node_password:depends("transit_node", "_http") + log = s:option(Flag, "log", translate("Enable") .. translate("Log")) log.default = "1" log.rmempty = false diff --git a/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm b/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm index 023f4de206..aef33e43af 100644 --- a/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm +++ b/package/lienol/luci-app-passwall/luasrc/view/passwall/node_list/link_share_man.htm @@ -180,11 +180,11 @@ local api = require "luci.model.cbi.passwall.api.api" "@" + v_server.value + ":" + v_port.value + "/?"; if (opt.get("tls").checked) { - url += "tls=1"; url += opt.query("sni", "tls_serverName"); - url += opt.query("allowinsecure", "tls_allowInsecure"); - } else if (v_type === "Trojan-Go") { - url += "tls=0"; + if (v_type !== "Trojan-Go") { + url += "tls=1" + url += opt.query("allowinsecure", "tls_allowInsecure"); + } } if (v_type === "Trojan-Go") { if (!opt.get("tls").checked && opt.get("trojan_transport").value === "original") { @@ -214,7 +214,6 @@ local api = require "luci.model.cbi.passwall.api.api" ":" + opt.get("ss_aead_pwd").value; } url += "&encryption=" + encodeURIComponent(enc); - url += opt.query("mux", "mux"); } url += "#" + encodeURI(v_alias.value); } @@ -492,8 +491,10 @@ local api = require "luci.model.cbi.passwall.api.api" opt.set('address', m.hostname); opt.set('port', m.port || "443"); opt.set(opt.client ? 'password' : 'passwords', decodeURIComponent(password)); - opt.set('tls', (queryParam.tls && queryParam.tls === '1')); + opt.set('tls', '1'); opt.get('tls').dispatchEvent(event); + opt.set('tls_allowInsecure', '0'); + opt.set('tls_serverName', queryParam.peer || queryParam.sni || ''); var plugin = queryParam.plugin !== undefined; if (plugin) { opt.set('trojan_transport', 'original'); @@ -510,13 +511,6 @@ local api = require "luci.model.cbi.passwall.api.api" } else alert(queryParam.plugin); } - var tls = !plugin && queryParam.tls === '1'; - opt.set('tls', tls); - opt.get('tls').dispatchEvent(event); - if (tls) { - opt.set('tls_serverName', queryParam.peer || queryParam.sni || ''); - opt.set('tls_allowInsecure', queryParam.allowinsecure === '1'); - } var tran = 'original'; var or = queryParam.type === undefined || queryParam.type === 'original'; var ws = queryParam.type.indexOf('ws') !== -1; @@ -549,7 +543,7 @@ local api = require "luci.model.cbi.passwall.api.api" opt.set('ss_aead_method', enc.method.toLowerCase() || ''); opt.set('ss_aead_pwd', enc.password || ''); } - opt.set('mux', queryParam.mux === '1'); + opt.set('mux', '1'); if (m.hash) { opt.set('remarks', decodeURI(m.hash.substr(1))); } diff --git a/package/lienol/luci-app-passwall/po/zh-cn/passwall.po b/package/lienol/luci-app-passwall/po/zh-cn/passwall.po index 078649127c..9c4cc3c418 100644 --- a/package/lienol/luci-app-passwall/po/zh-cn/passwall.po +++ b/package/lienol/luci-app-passwall/po/zh-cn/passwall.po @@ -421,12 +421,12 @@ msgstr "黑洞" msgid "Use the default node for the transit." msgstr "使用默认节点代理转发。" -msgid "Use the under node for the transit." -msgstr "使用下面的节点代理转发。" - msgid "No shunt rules? Click me to go to add." msgstr "没有分流规则?点我前往去添加。" +msgid "Use this node proxy to forward the default node." +msgstr "使用此节点代理转发默认节点。" + msgid "Domain Strategy" msgstr "域名解析策略" @@ -757,6 +757,9 @@ msgstr "Xray 资源文件目录" msgid "This variable specifies a directory where geoip.dat and geosite.dat files are." msgstr "此变量指定geoip.dat和geosite.dat文件所在的目录。" +msgid "Please note attention to the priority, the higher the order, the higher the priority." +msgstr "请注意优先级问题,排序越上面优先级越高。" + msgid "Update..." msgstr "更新中" @@ -1102,6 +1105,12 @@ msgstr "是否接收 PROXY protocol,当该节点要被回落或被代理转发 msgid "transit node" msgstr "中转到此节点" +msgid "Custom Socks" +msgstr "自定义 Socks" + +msgid "Custom HTTP" +msgstr "自定义 HTTP" + msgid "Bind Local" msgstr "本机监听" 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 9cfca3ff48..79ea5f1d66 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 @@ -324,7 +324,7 @@ load_config() { DNS_MODE=$(config_t_get global dns_mode pdnsd) DNS_FORWARD=$(config_t_get global dns_forward 8.8.4.4:53 | sed 's/:/#/g') DNS_CACHE=$(config_t_get global dns_cache 0) - LOCAL_DNS=$(config_t_get global up_china_dns default | sed 's/:/#/g') + LOCAL_DNS="default" if [ "${LOCAL_DNS}" = "default" ]; then DEFAULT_DNS=$(uci show dhcp | grep "@dnsmasq" | grep "\.server=" | awk -F '=' '{print $2}' | sed "s/'//g" | tr ' ' ',') if [ -z "${DEFAULT_DNS}" ]; then @@ -776,19 +776,6 @@ stop_crontab() { } start_dns() { - if [ "${LOCAL_DNS}" = "xray_doh" ]; then - _doh=$(config_t_get global up_china_dns_doh "https://dns.alidns.com/dns-query,223.5.5.5") - _doh_url=$(echo $_doh | awk -F ',' '{print $1}') - _doh_host_port=$(echo $_doh_url | sed "s/https:\/\///g" | awk -F '/' '{print $1}') - _doh_host=$(echo $_doh_host_port | awk -F ':' '{print $1}') - _doh_port=$(echo $_doh_host_port | awk -F ':' '{print $2}') - _doh_bootstrap=$(echo $_doh | cut -d ',' -sf 2-) - lua $API_GEN_XRAY -dns_listen_port "${LOCAL_DOH_PORT}" -dns_server "${_doh_bootstrap}" -doh_url "${_doh_url}" -doh_host "${_doh_host}" > $TMP_PATH/DNS1.json - ln_start_bin "$(first_type $(config_t_get global_app xray_file) xray)" xray $TMP_PATH/DNS1.log -config="$TMP_PATH/DNS1.json" - LOCAL_DNS="127.0.0.1#${LOCAL_DOH_PORT}" - unset _doh _doh_url _doh_bootstrap - fi - local pdnsd_forward other_port msg dns_listen_port=${DNS_PORT} pdnsd_forward=${DNS_FORWARD} @@ -974,7 +961,7 @@ add_dnsmasq() { local shunt_ids=$(uci show $CONFIG | grep "=shunt_rules" | awk -F '.' '{print $2}' | awk -F '=' '{print $1}') for shunt_id in $shunt_ids; do local shunt_node_id=$(config_n_get $TCP_NODE ${shunt_id} nil) - if [ "$shunt_node_id" = "nil" ] || [ "$shunt_node_id" = "_direct" ] || [ "$shunt_node_id" = "_blackhole" ]; then + if [ "$shunt_node_id" = "nil" ] || [ "$shunt_node_id" = "_default" ] || [ "$shunt_node_id" = "_direct" ] || [ "$shunt_node_id" = "_blackhole" ]; then continue fi local shunt_node=$(config_n_get $shunt_node_id address nil) 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 c14fd0826c..ea939ac8d5 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 @@ -208,6 +208,7 @@ load_acl() { msg2="${msg2}[$?]除${tcp_no_redir_ports}外的" } msg2="${msg2}所有端口" + $ipt_tmp -A PSW $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -d 1.2.3.4 $(REDIRECT $tcp_port $is_tproxy) $ipt_tmp -A PSW $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $tcp_redir_ports "-m multiport --dport") $(dst $IPSET_SHUNTLIST) $(REDIRECT $tcp_port $is_tproxy) $ipt_tmp -A PSW $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $tcp_redir_ports "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $tcp_port $is_tproxy) $ipt_tmp -A PSW $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $tcp_redir_ports "-m multiport --dport") $(get_redirect_ipt $tcp_proxy_mode $tcp_port $is_tproxy) @@ -234,6 +235,7 @@ load_acl() { msg2="${msg2}[$?]除${udp_no_redir_ports}外的" } msg2="${msg2}所有端口" + $ipt_m -A PSW $(comment "$remarks") -p tcp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") -d 1.2.3.4 $(REDIRECT $udp_port TPROXY) $ipt_m -A PSW $(comment "$remarks") -p udp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $udp_redir_ports "-m multiport --dport") $(dst $IPSET_SHUNTLIST) $(REDIRECT $udp_port TPROXY) $ipt_m -A PSW $(comment "$remarks") -p udp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $udp_redir_ports "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $udp_port TPROXY) $ipt_m -A PSW $(comment "$remarks") -p udp $(factor $ip "-s") $(factor $mac "-m mac --mac-source") $(factor $udp_redir_ports "-m multiport --dport") $(get_redirect_ipt $udp_proxy_mode $udp_port TPROXY) @@ -275,6 +277,7 @@ load_acl() { fi [ "$TCP_NO_REDIR_PORTS" != "disable" ] && msg="${msg}除${TCP_NO_REDIR_PORTS}外的" msg="${msg}所有端口" + $ipt_tmp -A PSW $(comment "默认") -p tcp -d 1.2.3.4 $(REDIRECT $TCP_REDIR_PORT $is_tproxy) $ipt_tmp -A PSW $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_SHUNTLIST) $(REDIRECT $TCP_REDIR_PORT $is_tproxy) $ipt_tmp -A PSW $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $TCP_REDIR_PORT $is_tproxy) $ipt_tmp -A PSW $(comment "默认") -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $TCP_PROXY_MODE $TCP_REDIR_PORT $is_tproxy) @@ -303,6 +306,7 @@ load_acl() { msg="UDP默认代理:使用UDP节点 [$(get_action_chain_name $UDP_PROXY_MODE)](TPROXY:${UDP_REDIR_PORT})代理" [ "$UDP_NO_REDIR_PORTS" != "disable" ] && msg="${msg}除${UDP_NO_REDIR_PORTS}外的" msg="${msg}所有端口" + $ipt_m -A PSW $(comment "默认") -p udp -d 1.2.3.4 $(REDIRECT $UDP_REDIR_PORT TPROXY) $ipt_m -A PSW $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_SHUNTLIST) $(REDIRECT $UDP_REDIR_PORT TPROXY) $ipt_m -A PSW $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT $UDP_REDIR_PORT TPROXY) $ipt_m -A PSW $(comment "默认") -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $UDP_PROXY_MODE $UDP_REDIR_PORT TPROXY) @@ -638,12 +642,12 @@ 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 echolog " - [$?]不代理TCP 端口:$TCP_NO_REDIR_PORTS" } + $ipt_tmp -A PSW_OUTPUT -p tcp -d 1.2.3.4 $blist_r $ipt_tmp -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_SHUNTLIST) $blist_r $ipt_tmp -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $blist_r $ipt_tmp -A PSW_OUTPUT -p tcp $(factor $TCP_REDIR_PORTS "-m multiport --dport") $p_r @@ -731,12 +735,12 @@ 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 echolog " - [$?]不代理 UDP 端口:$UDP_NO_REDIR_PORTS" } + $ipt_m -A PSW_OUTPUT -p udp -d 1.2.3.4 $(REDIRECT 1 MARK) $ipt_m -A PSW_OUTPUT -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_SHUNTLIST) $(REDIRECT 1 MARK) $ipt_m -A PSW_OUTPUT -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(dst $IPSET_BLACKLIST) $(REDIRECT 1 MARK) $ipt_m -A PSW_OUTPUT -p udp $(factor $UDP_REDIR_PORTS "-m multiport --dport") $(get_redirect_ipt $LOCALHOST_UDP_PROXY_MODE 1 MARK) diff --git a/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua b/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua index 24614020ca..c53fe91d30 100755 --- a/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua +++ b/package/lienol/luci-app-passwall/root/usr/share/passwall/subscribe.lua @@ -473,7 +473,6 @@ local function processData(szType, content, add_mode) end if params.peer then peer = params.peer end sni = params.sni and params.sni or "" - if params.mux and params.mux == "1" then result.mux = "1" end if params.ws and params.ws == "1" then result.trojan_transport = "ws" if params.wshost then result.ws_host = params.wshost end @@ -486,9 +485,10 @@ local function processData(szType, content, add_mode) if params.sspasswd then result.ss_aead_pwd = params.sspasswd end end result.port = port - if result.mux or result.trojan_transport == "ws" or result.ss_aead then + if result.trojan_transport == "ws" or result.ss_aead then result.type = "Trojan-Go" result.fingerprint = "firefox" + result.mux = "1" end result.tls = '1' result.tls_serverName = peer and peer or sni @@ -525,19 +525,14 @@ local function processData(szType, content, add_mode) result.address = hostInfo and hostInfo[1] or Info[2] end local peer, sni = nil, "" - local allowInsecure = allowInsecure_default local query = split(Info[2], "?") local params = {} for _, v in pairs(split(query[2], '&')) do local t = split(v, '=') params[string.lower(t[1])] = UrlDecode(t[2]) end - if params.allowinsecure then - allowInsecure = params.allowinsecure - end if params.peer then peer = params.peer end sni = params.sni and params.sni or "" - if params.mux and params.mux == "1" then result.mux = "1" end if params.type and params.type == "ws" then result.trojan_transport = "ws" if params.host then result.ws_host = params.host end @@ -551,9 +546,10 @@ local function processData(szType, content, add_mode) end result.port = port result.fingerprint = "firefox" - result.tls = '1' + result.tls = "1" result.tls_serverName = peer and peer or sni - result.tls_allowInsecure = allowInsecure and "1" or "0" + result.tls_allowInsecure = "0" + result.mux = "1" end elseif szType == "ssd" then result.type = "SS" diff --git a/target/sdk/files/Config.in b/target/sdk/files/Config.in index 2b8add64d0..abf5b70fae 100644 --- a/target/sdk/files/Config.in +++ b/target/sdk/files/Config.in @@ -18,6 +18,52 @@ menu "Global build settings" bool "Cryptographically sign package lists" default y + comment "Package build options" + + config DEBUG + bool + prompt "Compile packages with debugging info" + default n + help + Adds -g3 to the CFLAGS. + + comment "Stripping options" + + choice + prompt "Binary stripping method" + default USE_STRIP if EXTERNAL_TOOLCHAIN + default USE_STRIP if USE_GLIBC + default USE_SSTRIP + help + Select the binary stripping method you wish to use. + + config NO_STRIP + bool "none" + help + This will install unstripped binaries (useful for native + compiling/debugging). + + config USE_STRIP + bool "strip" + help + This will install binaries stripped using strip from binutils. + + config USE_SSTRIP + bool "sstrip" + depends on !USE_GLIBC + help + This will install binaries stripped using sstrip. + endchoice + + config STRIP_ARGS + string + prompt "Strip arguments" + depends on USE_STRIP + default "--strip-unneeded --remove-section=.comment --remove-section=.note" if DEBUG + default "--strip-all" + help + Specifies arguments passed to the strip command when stripping binaries. + endmenu menu "Advanced configuration options (for developers)"