luci-app-serverchan: sync with upstream source

This commit is contained in:
CN_SZTL 2020-01-15 01:15:02 +08:00
parent fc06148e99
commit 9daea4eb2f
No known key found for this signature in database
GPG Key ID: 6850B6345C862176
5 changed files with 836 additions and 174 deletions

View File

@ -9,18 +9,9 @@ LUCI_TITLE:=LuCI support for serverchan
LUCI_DEPENDS:=+iputils-arping +curl
LUCI_PKGARCH:=all
PKG_NAME:=luci-app-serverchan
PKG_VERSION:=1.21
PKG_VERSION:=1.26
PKG_RELEASE:=42
include $(TOPDIR)/feeds/luci/luci.mk
define Package/$(PKG_NAME)/postinst
#!/bin/sh
chmod 0755 /etc/init.d/serverchan
chmod 0755 /usr/bin/serverchan/serverchan
/etc/init.d/serverchan enable
exit 0
endef
# call BuildPackage - OpenWrt buildroot signature

View File

@ -5,10 +5,15 @@ local net = require "luci.model.network".init()
local sys = require "luci.sys"
local ifaces = sys.net:devices()
m=Map("serverchan",translate("ServerChan"),translate("「Server酱」英文名「ServerChan」是一款从服务器推送报警信息和日志到微信的工具。"))
m=Map("serverchan",translate("ServerChan"),
translate("「Server酱」英文名「ServerChan」是一款从服务器推送报警信息和日志到微信的工具。<br /><br />如果你在使用中遇到问题,请到这里提交:")
.. [[<a href="https://github.com/tty228/luci-app-serverchan" target="_blank">]]
.. translate("github 项目地址")
.. [[</a>]]
)
m:section(SimpleSection).template = "serverchan/serverchan_status"
s=m:section(NamedSection,"serverchan","serverchan",translate("Server酱设置"))
s:tab("tab_basic", translate("基本设置"))
s:tab("tab_basic2", translate("设备状态"))
@ -51,9 +56,56 @@ end
e.write=function(e,e,e)
end
a=s:taboption("tab_basic2", Flag,"serverchan_ip",translate("WAN ip 变化通知"))
a.default=0
a.rmempty=true
a=s:taboption("tab_basic2", ListValue,"serverchan_ipv4",translate("ipv4 变动通知"))
a.default="disable"
a:value("0",translate("关闭"))
a:value("1",translate("通过接口获取"))
a:value("2",translate("通过URL获取"))
a = s:taboption("tab_basic2", ListValue, "ipv4_interface", translate("接口名称"))
a:depends({serverchan_ipv4="1"})
for _, iface in ipairs(ifaces) do
if not (iface == "lo" or iface:match("^ifb.*")) then
local nets = net:get_interface(iface)
nets = nets and nets:get_networks() or {}
for k, v in pairs(nets) do
nets[k] = nets[k].sid
end
nets = table.concat(nets, ",")
a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface))
end
end
a.description = translate("<br/>一般选择 wan 接口,多拨环境请自行选择")
a= s:taboption("tab_basic2", Value, "ipv4_URL", "URL 地址")
a.rmempty = true
a.default = "members.3322.org/dyndns/getip"
a:depends({serverchan_ipv4="2"})
a.description = translate("<br/>会因服务器稳定性/连接频繁等原因导致获取失败,一般不推荐")
a=s:taboption("tab_basic2", ListValue,"serverchan_ipv6",translate("ipv6 变动通知"))
a.default="disable"
a:value("0",translate("关闭"))
a:value("1",translate("通过接口获取"))
a:value("2",translate("通过URL获取"))
a = s:taboption("tab_basic2", ListValue, "ipv6_interface", translate("接口名称"))
a:depends({serverchan_ipv6="1"})
for _, iface in ipairs(ifaces) do
if not (iface == "lo" or iface:match("^ifb.*")) then
local nets = net:get_interface(iface)
nets = nets and nets:get_networks() or {}
for k, v in pairs(nets) do
nets[k] = nets[k].sid
end
nets = table.concat(nets, ",")
a:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface))
end
end
a.description = translate("<br/>一般选择 wan 接口,多拨环境请自行选择")
a= s:taboption("tab_basic2", Value, "ipv6_URL", "URL 地址")
a.rmempty = true
a.default = "v6.ip.zxinc.org/getip"
a:depends({serverchan_ipv6="2"})
a.description = translate("<br/>会因服务器稳定性/连接频繁等原因导致获取失败,一般不推荐")
a=s:taboption("tab_basic2", Flag,"serverchan_up",translate("设备上线通知"))
a.default=0
a.rmempty=true
@ -134,8 +186,8 @@ end
sheep=s:taboption("tab_basic4", ListValue,"serverchan_sheep",translate("免打扰时段设置"),translate("在指定整点时间段内,暂停推送消息<br/>免打扰时间中,定时推送也会被阻止。"))
sheep:value("0",translate("关闭"))
sheep:value("1",translate("模式一:脚本挂起,不检测设备"))
--[[sheep:value("2",translate("模式二:脚本继续运行但不发送消息"))--]]
sheep:value("1",translate("模式一:脚本挂起,延迟发送"))
sheep:value("2",translate("模式二:静默模式,不发送任何信息"))
sheep.rmempty = true
sheep.optional = true
sheep=s:taboption("tab_basic4", ListValue,"starttime",translate("免打扰开始时间"))
@ -186,10 +238,9 @@ for _, iface in ipairs(ifaces) do
n:value(iface, ((#nets > 0) and "%s (%s)" % {iface, nets} or iface))
end
end
local apply = luci.http.formvalue("cbi.apply")
if apply then
io.popen("/etc/init.d/serverchan start")
end
return m
return m

View File

@ -1,4 +1,4 @@
#!/bin/bash
#!/bin/sh
# 读取设置文件
function get_config(){
@ -9,18 +9,38 @@ function get_config(){
}
function read_config(){
debuglevel=`get_config debuglevel`
if [ -z "$debuglevel" ] ; then logfile="/dev/null";else logfile="/tmp/serverchan/server_chan.log";fi
serverchan_enable=`get_config serverchan_enable`
if [ -z "$serverchan_enable" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取程序开关 " >> ${logfile};fi
#if [ -z "$serverchan_enable" ] || [ "$serverchan_enable" -eq "0" ] ; then exit;fi
serverchan_sckey=`get_config sckey`
serverchan_ip=`get_config serverchan_ip`
if [ -z "$serverchan_sckey" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 SCKEY" >> ${logfile};fi
if [ -z "$serverchan_sckey" ] && [ "${#serverchan_sckey}" -lt "50" ] ; then echo "`date "+%H:%M:%S"` 【!!!】请填入正确的 SCKEY " >> ${logfile};fi
if [ -z "$serverchan_sckey" ] && [ "${#serverchan_sckey}" -lt "50" ] ; then exit;fi
serverchan_ipv4=`get_config serverchan_ipv4`
if [ -z "$serverchan_ipv4" ] || [ "$serverchan_ipv4" -ne "0" ] && [ "$serverchan_ipv4" -ne "1" ] && [ "$serverchan_ipv4" -ne "2" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 ipv4 变化通知 开关" >> ${logfile};fi
ipv4_interface=`get_config ipv4_interface`
if [ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "1" ] && [ -z "$ipv4_interface" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 ipv4 IP 接口信息" >> ${logfile};fi
ipv4_URL=`get_config ipv4_URL`
if [ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "2" ] && [ -z "$ipv4_URL" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 ipv4 IP URL信息" >> ${logfile};fi
serverchan_ipv6=`get_config serverchan_ipv6`
if [ -z "$serverchan_ipv6" ] || [ "$serverchan_ipv6" -ne "0" ] && [ "$serverchan_ipv6" -ne "1" ] && [ "$serverchan_ipv6" -ne "2" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 ipv6 变化通知 开关" >> ${logfile};fi
ipv6_interface=`get_config ipv6_interface`
if [ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "1" ] && [ -z "$ipv6_interface" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 ipv6 IP 接口信息" >> ${logfile};fi
ipv6_URL=`get_config ipv6_URL`
if [ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "2" ] && [ -z "$ipv6_URL" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 ipv6 IP URL信息" >> ${logfile};fi
serverchan_up=`get_config serverchan_up`
if [ -z "$serverchan_up" ] || [ "$serverchan_up" -ne "0" ] && [ "$serverchan_up" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 设备上线提醒 开关" >> ${logfile};fi
serverchan_down=`get_config serverchan_down`
if [ -z "$serverchan_down" ] || [ "$serverchan_down" -ne "0" ] && [ "$serverchan_down" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 设备下线提醒 开关" >> ${logfile};fi
serverchan_sheep=`get_config serverchan_sheep`
if [ -z "$serverchan_sheep" ] ; then serverchan_sheep="0";fi
serverchan_whitelist=`get_config serverchan_whitelist`
serverchan_blacklist=`get_config serverchan_blacklist`
serverchan_interface=`get_config serverchan_interface`
device_aliases=`get_config device_aliases`
if [ -z "$device_aliases" ] ; then device_aliases=`echo $device_aliases | sed 's/ /\n/g' | sed 's/-/ /g'`;fi
if [ ! -z "$device_aliases" ] ; then device_aliases=`echo $device_aliases | sed 's/ /\n/g' | sed 's/-/ /g'`;fi
starttime=`get_config starttime`
endtime=`get_config endtime`
sleeptime=60
@ -29,16 +49,6 @@ function read_config(){
temperature_enable=`get_config temperature_enable`
temperature=`get_config temperature`
dir="/tmp/serverchan/"
debuglevel=`get_config debuglevel`
if [ -z "$debuglevel" ] ; then logfile="/dev/null";else logfile="/tmp/serverchan/server_chan.log";fi
if [ -z "$serverchan_enable" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取程序开关 " >> ${logfile};fi
if [ -z "$serverchan_enable" ] || [ "$serverchan_enable" -eq "0" ] ; then exit;fi
if [ -z "$serverchan_sckey" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 SCKEY" >> ${logfile};fi
if [ -z "$serverchan_sckey" ] ; then exit;fi
if [ -z "$serverchan_sckey" ] && [ "${#serverchan_sckey}" -lt "50" ] ; then echo "`date "+%H:%M:%S"` 【!!!】请填入正确的 SCKEY " >> ${logfile};fi
if [ -z "$serverchan_ip" ] || [ "$serverchan_ip" -ne "0" ] && [ "$serverchan_ip" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 ip 变化通知 开关" >> ${logfile};fi
if [ -z "$serverchan_up" ] || [ "$serverchan_up" -ne "0" ] && [ "$serverchan_up" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 设备上线提醒 开关" >> ${logfile};fi
if [ -z "$serverchan_down" ] || [ "$serverchan_down" -ne "0" ] && [ "$serverchan_down" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【!!!】无法读取 设备下线提醒 开关" >> ${logfile};fi
}
#等待 5s确保 luci 设置已保存
@ -71,24 +81,24 @@ Temperature_n=0
cpuload_n=0
send_enable=0
echo "`date "+%H:%M:%S"` 【初始化】载入配置文件" >> ${logfile}
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】工作目录为 $dir " >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】log 目录为 $logfile " >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】工作目录为 $dir " >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】log 目录为 $logfile " >> ${logfile};fi
# 如果 “忽略列表 为空” 并且 “关注列表为空”
if [ -z "$serverchan_whitelist" ] && [ -z "$serverchan_blacklist" ] && [ -z "$serverchan_interface" ]; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】未启用 MAC 过滤" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】未启用 MAC 过滤" >> ${logfile};fi
# 如果 “忽略列表不为空”
elif [ ! -z "$serverchan_whitelist" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】忽略列表内设备" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】忽略列表内设备" >> ${logfile};fi
# 如果 “关注列表不为空”
elif [ ! -z "$serverchan_blacklist" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】仅关注列表内设备" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】仅关注列表内设备" >> ${logfile};fi
# 如果 “仅关注接口选项打开”
elif [ ! -z "$serverchan_interface" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】仅关注接口内设备" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【初始化】仅关注接口内设备" >> ${logfile};fi
fi
}
@ -139,43 +149,43 @@ fi
#免打扰检测
function serverchan_disturb(){
if [ ! -z "$serverchan_sheep" ] && [ "$serverchan_sheep" -eq "1" ] && [ ! -z "$starttime" ] && [ ! -z "$endtime" ] ;then
if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then enable=1;else enable=0;fi
if [ ! -z "$serverchan_sheep" ] && [ "$serverchan_sheep" -eq "1" ] && [ ! -z "$starttime" ] && [ ! -z "$endtime" ] ;then
if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then enable=1;else enable=0;fi
if [ "$enable" -eq "0" ] ;then
sheep_str=0
while [ $enable -eq "0" ] ;
do
if [ "$sheep_str" -eq "0" ] ; then
echo "`date "+%H:%M:%S"` 【免打扰】夜深了,该休息了" >> ${logfile}
sheep_str=1
if [ "$enable" -eq "0" ] ;then
sheep_str=0
while [ $enable -eq "0" ] ;
do
if [ "$sheep_str" -eq "0" ] ; then
echo "`date "+%H:%M:%S"` 【免打扰】夜深了,该休息了" >> ${logfile}
sheep_str=1
fi
read_config
if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then
enable=1
else
enable=0
enable_detection 1
fi
continue
done
unset title
unset content
rm -f ${dir}title >/dev/null 2>&1
rm -f ${dir}content >/dev/null 2>&1
fi
read_config
if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then
enable=1
else
enable=0
enable_detection 1
fi
continue
done
unset title
unset content
rm -f ${dir}title >/dev/null 2>&1
rm -f ${dir}content >/dev/null 2>&1
fi
fi
}
#清理日志
function clean_log(){
logrow=$(grep -c "" ${logfile})
if [ $logrow -gt 500 ] ;then
#cat /dev/null > ${logfile}
sed -i '1,100d' ${logfile}
echo "`date "+%H:%M:%S"` 【清理】日志超出上限,删除前 100 条" >> ${logfile}
fi
logrow=$(grep -c "" ${logfile})
if [ $logrow -gt 500 ] ;then
#cat /dev/null > ${logfile}
sed -i '1,100d' ${logfile}
echo "`date "+%H:%M:%S"` 【清理】日志超出上限,删除前 100 条" >> ${logfile}
fi
}
if [ -f ${logfile} ] ; then clean_log;fi
@ -194,6 +204,82 @@ else
fi
}
# 流量数据
function usage(){
if [ -f "/usr/bin/serverchan/wrtbwmon/wrtbwmon" ] && [ -f "/usr/bin/serverchan/wrtbwmon/readDB.awk" ] ; then
/usr/bin/serverchan/wrtbwmon/wrtbwmon update ${dir}usage.db
else
echo "`date "+%H:%M:%S"` 【!!!】流量数据文件缺失" >> ${logfile}
fi
}
function usage_ip(){
if [ "$1" ] ;then
ip=`cat /tmp/serverchan/usage.db | grep -w $1`
if [ ! -z "$ip" ] ; then ip=`echo $ip | sed 's/,/ /g'`;fi
if [ ! -z "$ip" ] ; then ip_total=`echo $ip | awk '{print $6}'`;fi
if [ ! -z "$ip_total" ] ; then echo `bytes_for_humans $ip_total`;fi
fi
}
# 流量数据剔除ip
function usage_down(){
if [ ! -f "${dir}usage.db" ] ; then return;fi
if [ "$1" ] ;then
sed -i "/$1/d" ${dir}usage.db
logrow_usage=$(grep -c "" ${dir}usage.db)
if [ $logrow_usage -le "1" ] ;then
rm -f ${dir}usage.db
fi
fi
}
# 流量数据单位换算
# bytes_for_humans 1024
function bytes_for_humans {
if [ "$1" ] ;then
if [[ $1 -lt 1024 ]]; then
echo $1 bytes
elif [[ $1 -lt 1048576 ]]; then
echo `awk 'BEGIN{printf "%.2f\n",'$1'/'1024'}'` KB
elif [[ $1 -lt 1073741824 ]]; then
echo `awk 'BEGIN{printf "%.2f\n",'$1'/'1048576'}'` MB
else
echo `awk 'BEGIN{printf "%.2f\n",'$1'/'1073741824'}'` GB
fi
else
echo 0bytes
fi
}
# 时间单位换算
# time_for_humans 1024
function time_for_humans {
if [ "$1" ] ;then
if [[ $1 -lt 60 ]]; then
echo $1 秒
elif [[ $1 -lt 3600 ]]; then
usetime_min=`expr $1 / 60`
usetime_sec=`expr $usetime_min \* 60`
usetime_sec=`expr $1 - ${usetime_sec}`
echo $usetime_min 分钟 $usetime_sec 秒
elif [[ $1 -lt 216000 ]]; then
usetime_hour=`expr $1 / 3600`
usetime_min=`expr $usetime_hour \* 3600`
usetime_min=`expr $1 - ${usetime_min}`
usetime_min=`expr ${usetime_min} / 60`
echo $usetime_hour 小时 $usetime_min 分
else
usetime_day=`expr $1 / 86400`
usetime_hour=`expr $usetime_day \* 86400`
usetime_hour=`expr $1 - ${usetime_hour}`
usetime_hour=`expr ${usetime_hour} / 3600`
echo $usetime_day 天 $usetime_hour 小时
fi
else
echo 0 秒
fi
}
#检测设备上线
function up(){
if [ ! -f "${dir}ipAddress" ] ; then > ${dir}ipAddress;fi
@ -205,7 +291,7 @@ if [ "$1" ] ;then
# 如果 ipAddress 文件中存在此ip则跳过待断线检测
ip_mac=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $2}' | grep -v "^$" | sort -u )
if [ -z "$ip_mac" ] ; then ip_mac=$( cat /proc/net/arp | grep "0x2" | grep -w $1 | awk '{print $4}' | grep -v "^$" | sort -u );fi
if [ ! -z "$device_aliases" ] && [ ! -z "$ip_mac" ] && ( echo "$device_aliases" | grep -q -i $ip_mac ); then
ip_name=$( echo "$device_aliases" | grep -i $ip_mac |awk '{print $2}' | grep -v "^$" | sort -u )
else
@ -215,14 +301,14 @@ if [ "$1" ] ;then
if [ -z "$ip_mac" ] ; then ip_mac="unknown";fi
if [ -z "$ip_name" ] ; then ip_name="unknown";fi
local ip_ms=`echo $( arping -I $( cat /proc/net/arp | grep -w $1 | awk '{print $6}' | grep -v "^$" | sort -u ) -c 10 -f -w 3 $1)`
local ip_ms=`echo $( arping -I $( cat /proc/net/arp | grep -w $1 | awk '{print $6}' | grep -v "^$" | sort -u ) -c 10 -f -w 1 $1)`
if ( ! echo ${ip_ms} | grep -q ms );then
local ip_ms=`ping -c 1 -w 2 $1`
local ip_ms=`ping -c 1 -w 1 $1`
if ( ! echo ${ip_ms} | grep -q ms );then
sleep 2
local ip_ms=`echo $( arping -I $( cat /proc/net/arp | grep -w $1 | awk '{print $6}' | grep -v "^$" | sort -u ) -c 10 -f -w 5 $1)`
sleep 1
local ip_ms=`echo $( arping -I $( cat /proc/net/arp | grep -w $1 | awk '{print $6}' | grep -v "^$" | sort -u ) -c 10 -f -w 2 $1)`
fi
fi
@ -231,29 +317,27 @@ if [ "$1" ] ;then
if ( echo ${ip_ms} | grep -q ms ); then
# 如果连接成功
LockFile
LockFile
usage_down $1
if ( echo "$ip_mac" | grep -q "unknown" ) || ( echo "$ip_name" | grep -q "unknown" ) ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 获取 $1 $ip_mac 设备信息失败,重试中" >> ${logfile};fi
for i in `seq 1 5`
do
echo "`date "+%H:%M:%S"` 获取 $1 $ip_mac 设备信息失败,重试中" >> ${logfile}
sleep 1
ip_mac=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $2}' | grep -v "^$" | sort -u )
if [ -z "$ip_mac" ] ; then ip_mac=$( cat /proc/net/arp | grep "0x2" | grep -w $1 | awk '{print $4}' | grep -v "^$" | sort -u );fi
if [ ! -z "$device_aliases" ] && [ ! -z "$ip_mac" ] && ( echo "$device_aliases" | grep -q -i $ip_mac ); then
ip_name=$( echo "$device_aliases" | grep -i $ip_mac |awk '{print $2}' | grep -v "^$" | sort -u )
else
ip_name=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $4}' | grep -v "^$" | sort -u )
fi
if [ -z "$ip_mac" ] ; then ip_mac=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $2}' | grep -v "^$" | sort -u );fi
if [ -z "$ip_mac" ] ; then ip_mac=$( cat /proc/net/arp | grep "0x2" | grep -w $1 | awk '{print $4}' | grep -v "^$" | sort -u );fi
if [ ! -z "$device_aliases" ] && [ ! -z "$ip_mac" ] && ( echo "$device_aliases" | grep -q -i $ip_mac ); then ip_name=$( echo "$device_aliases" | grep -i $ip_mac |awk '{print $2}' | grep -v "^$" | sort -u );fi
if [ -z "$ip_name" ] ; then ip_name=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $4}' | grep -v "^$" | sort -u );fi
if [ ! -z "$ip_mac" ] && [ ! -z "$ip_name" ] ; then break;fi
done
fi
if [ -z "$ip_mac" ] ; then
ip_mac="unknown"
echo "`date "+%H:%M:%S"` 获取 $1 mac 超时,暂停跳过" >> ${logfile}
echo "`date "+%H:%M:%S"` 获取 $1 mac 超时,跳过" >> ${logfile}
fi
if [ -z "$ip_name" ] ; then
ip_name="unknown"
echo "`date "+%H:%M:%S"` 获取 $1 设备名超时,暂停跳过" >> ${logfile}
echo "`date "+%H:%M:%S"` 获取 $1 设备名超时,跳过" >> ${logfile}
fi
if [ ! -z "$send_enable" ] && [ "$send_enable" -ne 3 ] ; then
@ -271,7 +355,7 @@ if [ "$1" ] ;then
content="%0D%0A%0D%0A---%0D%0A%0D%0A####新设备连接%0D%0A%0D%0A"">$ip_name"
fi
#echo "$1 $( cat /var/dhcp.leases | grep -w $1 |awk '{print $2" "$4}' )" >> ${dir}ipAddress
echo "$1 $ip_mac $ip_name" >> ${dir}ipAddress
echo "$1 $ip_mac $ip_name `date +%s`" >> ${dir}ipAddress
echo "`date "+%H:%M:%S"` 【微信推送】新设备 $ip_name $1 连接了">> ${logfile}
if [ ! -z "$serverchan_blacklist" ] ; then
@ -285,18 +369,17 @@ if [ "$1" ] ;then
else
# 如果定时任务运行
echo "`date "+%H:%M:%S"` 新设备 $ip_name $1 连接了" >> ${logfile}
echo "$1 $ip_mac $ip_name" >> ${dir}ipAddress
echo "$1 $ip_mac $ip_name `date +%s`" >> ${dir}ipAddress
unset title
unset content
fi
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 设备 $ip_name $1 连接失败" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 设备 $ip_name $1 连接失败" >> ${logfile};fi
fi
rm -f ${dir}serverchan.lock >/dev/null 2>&1
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -eq "5" ] ; then echo "`date "+%H:%M:%S"` $ip_name $1 已存在,跳过" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -eq "5" ] ; then echo "`date "+%H:%M:%S"` $ip_name $1 已存在,跳过" >> ${logfile};fi
fi
unset ip_ms
fi
}
@ -311,26 +394,24 @@ if [ "$1" ] ;then
if [ -z "$ip_mac" ] ; then ip_mac=$( cat /proc/net/arp | grep "0x2" | grep -w $1 | awk '{print $4}' | grep -v "^$" | sort -u );fi
ip_name=$( cat ${dir}ipAddress | grep -w $1 |awk '{print $3}' | grep -v "^$" | sort -u )
if ( echo "$ip_mac" | grep -q "unknown" ) || ( echo "$ip_name" | grep -q "unknown" ) ; then
echo "`date "+%H:%M:%S"` $1 $ip_mac 无设备名,尝试重新读取" >> ${logfile}
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` $1 $ip_mac 无设备名,尝试重新读取" >> ${logfile};fi
time_up=$( cat ${dir}ipAddress | grep -w $ip |awk '{print $4}' | grep -v "^$" | sort -u )
if [ -z "$time_up" ] ; then time_up=`date +%s`;fi
sed -i "/$1/d" ${dir}ipAddress
ip_mac=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $2}' | grep -v "^$" | sort -u )
if [ -z "$ip_mac" ] ; then ip_mac=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $2}' | grep -v "^$" | sort -u );fi
if [ -z "$ip_mac" ] ; then ip_mac=$( cat /proc/net/arp | grep "0x2" | grep -w $1 | awk '{print $4}' | grep -v "^$" | sort -u );fi
if [ ! -z "$device_aliases" ] && [ ! -z "$ip_mac" ] && ( echo "$device_aliases" | grep -q -i $ip_mac ); then
ip_name=$( echo "$device_aliases" | grep -i $ip_mac |awk '{print $2}' | grep -v "^$" | sort -u )
else
ip_name=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $4}' | grep -v "^$" | sort -u )
fi
if [ ! -z "$device_aliases" ] && [ ! -z "$ip_mac" ] && ( echo "$device_aliases" | grep -q -i $ip_mac ); then ip_name=$( echo "$device_aliases" | grep -i $ip_mac |awk '{print $2}' | grep -v "^$" | sort -u );fi
if [ -z "$ip_name" ] ; then ip_name=$( cat /var/dhcp.leases | grep -w $1 |awk '{print $4}' | grep -v "^$" | sort -u );fi
if [ -z "$ip_mac" ] ; then ip_mac="unknown";fi
if [ -z "$ip_name" ] ; then ip_name="unknown";fi
echo "$1 $ip_mac $ip_name" >> ${dir}ipAddress
echo "$1 $ip_mac $ip_name $time_up" >> ${dir}ipAddress
fi
local ip_ms=`echo $( arping -I $( cat /proc/net/arp | grep -w $1 | awk '{print $6}' | grep -v "^$" | sort -u ) -c 10 -f -w 3 $1)`
local ip_ms=`echo $( arping -I $( cat /proc/net/arp | grep -w $1 | awk '{print $6}' | grep -v "^$" | sort -u ) -c 10 -f -w 10 $1)`
if ( ! echo ${ip_ms} | grep -q ms );then
local ip_ms=`ping -c 1 -w 2 $1`
local ip_ms=`ping -c 5 -w 5 $1`
if ( ! echo ${ip_ms} | grep -q ms );then
sleep 3
sleep 1
local ip_ms=`echo $( arping -I $( cat /proc/net/arp | grep -w $1 | awk '{print $6}' | grep -v "^$" | sort -u ) -c 10 -f -w 10 $1)`
fi
fi
@ -340,7 +421,7 @@ if [ "$1" ] ;then
if ( echo ${ip_ms} | grep -q ms ); then
# 如果连接成功
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 设备 $ip_name $1 依然坚挺" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 设备 $ip_name $1 依然坚挺" >> ${logfile};fi
else
# 如果连接失败
LockFile
@ -350,16 +431,20 @@ if [ "$1" ] ;then
# 如果打开了下线提醒
if [ -f "${dir}title" ] ; then title=`cat ${dir}title` ;fi
if [ -f "${dir}content" ] ; then content=`cat ${dir}content` ;fi
ip_total=`usage_ip $1`
time_down=`date +%s`
time_up=$( cat ${dir}ipAddress | grep -w $1 |awk '{print $4}' | grep -v "^$" | sort -u )
time1=$(($time_down-$time_up))
time1=`time_for_humans $time1`
if [ -z "$title" ] ; then
title="设备离线通知"
content="%0D%0A%0D%0A---%0D%0A%0D%0A####设备断开连接%0D%0A%0D%0A"">$ip_name"
content="%0D%0A%0D%0A---%0D%0A%0D%0A####设备断开连接%0D%0A%0D%0A"">$ip_name%0D%0A%0D%0A"">总计流量:$ip_total%0D%0A%0D%0A"">在线 $time1"
elif ( echo ${title} | grep -q "设备离线通知" ) ; then
title="设备离线通知"
content="%0D%0A%0D%0A"">$ip_name"
content="%0D%0A%0D%0A"">$ip_name%0D%0A%0D%0A"">总计流量:$ip_total%0D%0A%0D%0A"">在线 $time1"
else
title="设备状态变化"
content="%0D%0A%0D%0A---%0D%0A%0D%0A####设备断开连接%0D%0A%0D%0A"">$ip_name"
content="%0D%0A%0D%0A---%0D%0A%0D%0A####设备断开连接%0D%0A%0D%0A"">$ip_name%0D%0A%0D%0A"">总计流量:$ip_total%0D%0A%0D%0A"">在线 $time1"
fi
echo "`date "+%H:%M:%S"` 【微信推送】设备 $ip_name $1 断开连接 " >> ${logfile}
@ -368,6 +453,7 @@ if [ "$1" ] ;then
fi
echo "`date "+%H:%M:%S"` 设备 $ip_name $1 断开连接 " >> ${logfile}
sed -i "/$1/d" ${dir}ipAddress
usage_down $1
unset title
unset content
fi
@ -379,7 +465,7 @@ fi
#发送定时数据
function send(){
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 创建定时任务" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 创建定时任务" >> ${logfile};fi
uci set serverchan.serverchan.send_enable=3
uci commit serverchan
unset title
@ -395,13 +481,17 @@ function send(){
if [ ! -z "$router_status" ] && [ "$router_status" -eq "1" ] ; then send_content=${send_content}"%0D%0A%0D%0A"" 内存占用:`free -m | sed -n '2p' | awk '{print""($3/$2)*100"%"}'`";fi
if [ ! -z "$router_status" ] && [ "$router_status" -eq "1" ] ; then send_content=${send_content}"%0D%0A%0D%0A""`cat /proc/uptime| awk -F. '{run_days=$1 / 86400;run_hour=($1 % 86400)/3600;run_minute=($1 % 3600)/60;run_second=$1 % 60;printf(" 运行时间:%d天%d时%d分%d秒",run_days,run_hour,run_minute,run_second)}'`";fi
router_temp=`get_config router_temp`
if [ ! -z "$router_temp" ] && [ "$router_temp" -eq "1" ] ; then send_content=${send_content}"%0D%0A%0D%0A""---%0D%0A%0D%0A#### 设备温度%0D%0A%0D%0A CPU`cut -c1-2 /sys/class/thermal/thermal_zone0/temp`%e2%84%83";fi
if [ ! -z "$router_temp" ] && [ "$router_temp" -eq "1" ] ; then send_content=${send_content}"%0D%0A%0D%0A""---%0D%0A%0D%0A#### 设备温度%0D%0A%0D%0A CPU`cut -c1-2 /sys/class/thermal/thermal_zone*/temp`%e2%84%83";fi
router_wan=`get_config router_wan`
send_wanIP=$(ubus call network.interface.wan status | grep '\"address\"' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
send_hostIP=$(curl -k -s "http://members.3322.org/dyndns/getip")
send_wanIPv6=$(ip addr show|grep -v deprecated|grep -A1 'inet6 [^f:]'|sed -nr ':a;N;s#^ +inet6 ([a-f0-9:]+)/.+? scope global .*? valid_lft ([0-9]+sec) .*#\2 \1#p;ta'|sort -nr|head -n1|cut -d' ' -f2)
send_hostIP=$(curl -k -s -4 "http://members.3322.org/dyndns/getip")
send_hostIPv6=$(curl -k -s -6 v6.ip.zxinc.org/getip)
if [ ! -z "$router_wan" ] && [ "$router_wan" -eq "1" ] ; then
send_content=${send_content}"%0D%0A%0D%0A""---%0D%0A%0D%0A#### WAN 口信息%0D%0A%0D%0A WAN ip$send_wanIP"
send_content=${send_content}"%0D%0A%0D%0A""---%0D%0A%0D%0A#### WAN 口信息%0D%0A%0D%0A ip$send_wanIP"
send_content=${send_content}"%0D%0A%0D%0A"" 外网 ip$send_hostIP"
send_content=${send_content}"%0D%0A%0D%0A"" ipv6$send_wanIPv6"
send_content=${send_content}"%0D%0A%0D%0A"" 外网 ipv6$send_hostIPv6"
if [ ! -z "$send_content" ] && [ ! -z "$router_wan" ] ; then
if ( ! echo ${send_wanIP} | grep -q ${send_hostIP} );then send_content=${send_content}"%0D%0A%0D%0A"" 外网 ip 与接口 ip 不一致,你的 ip 不是公网 ip";fi
else
@ -411,7 +501,7 @@ function send(){
fi
client_list=`get_config client_list`
if [ ! -z "$client_list" ] && [ "$client_list" -eq "1" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 检测客户端列表" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 检测客户端列表" >> ${logfile};fi
if [ ! -f "${dir}ipAddress" ] ; then > ${dir}ipAddress;fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【连接】开始进行设备下线检测" >> ${logfile};fi
@ -436,27 +526,36 @@ function send(){
if [ "$IPLISTrow" -eq $(grep -c "" ${dir}ipAddress) ] ; then echo "`date "+%H:%M:%S"` 没有新设备连接" >> ${logfile};fi
send_content=${send_content}"%0D%0A%0D%0A---%0D%0A%0D%0A#### 在线设备%0D%0A%0D%0A";
IPLIST=$( cat ${dir}ipAddress| awk '{print $1" "$3}' )
n=0
ip=$( cat ${dir}ipAddress | awk '{print $1"}' )
for ip in $IPLIST; do
n=$(($n+1))
if [ "${#ip}" -gt "20" ] ; then ip=`echo ${ip:0:20}"*"`;fi
[ $((n%2)) -eq 1 ] && send_content=${send_content}"%0D%0A%0D%0A"" $ip "
[ $((n%2)) -eq 0 ] && send_content=${send_content}"$ip"
send_content=${send_content}"%0D%0A%0D%0A"" $ip "
ip_total=`usage_ip $ip`
time_down=`date +%s`
time_up=$( cat ${dir}ipAddress | grep -w $ip |awk '{print $4}' | grep -v "^$" | sort -u )
time1=$(($time_down-$time_up))
time1=`time_for_humans $time1`
send_content=${send_content}"`cat ${dir}ipAddress | grep "$ip" | awk '{print $3}' | grep -v "^$" | sort -u`%0D%0A%0D%0A"" 总计流量:$ip_total 在线 $time1"
done
fi
send_title=$( echo $send_title | sed $'s/\ /%20/g'| sed $'s/\"/%22/g'| sed $'s/\#/%23/g'| sed $'s/\&/%26/g'| sed $'s/\,/%2C/g'| sed $'s/\//%2F/g'| sed $'s/\:/%3A/g'| sed $'s/\;/%3B/g'| sed $'s/\=/%3D/g'| sed $'s/\@/%40/g')
content=$( echo $content| sed $'s/unknown/%e6%9c%aa%e7%9f%a5%e8%ae%be%e5%a4%87/')
#send_content=$( echo $send_content | sed $'s/\ /%20/g'| sed $'s/\"/%22/g'| sed $'s/\#/%23/g'| sed $'s/\&/%26/g'| sed $'s/\,/%2C/g'| sed $'s/\//%2F/g'| sed $'s/\:/%3A/g'| sed $'s/\;/%3B/g'| sed $'s/\=/%3D/g'| sed $'s/\@/%40/g')
#未转义 | sed $'s/\(/%28/g' | sed $'s/\)/%29/g' | sed $'s/\+/%2B/g' | sed $'s/\%/%25/g' | sed $'s/\</%3C/g' | sed $'s/\>/%3E/g' | sed $'s/\?/%3F/g' | sed $'s/\\/%5C/g' | sed $'s/\|/%7C/g'
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 进行 URL 编码,标题=$send_title" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 进行 URL 编码,标题=$send_title" >> ${logfile};fi
if [ -z "$send_content" ] ; then
send_content="%0D%0A%0D%0A---%0D%0A%0D%0A#### 我遇到了一个难题%0D%0A%0D%0A>你没有选择需要发送的项目,该怎么办呢%0D%0A%0D%0A---";
echo "`date "+%H:%M:%S"` 【!!!】定时发送选项错误,请检查你的设置" >> ${logfile}
fi
nowtime=`date "+%Y-%m-%d %H:%M:%S"`
curl -s "http://sc.ftqq.com/$serverchan_sckey.send?text=${send_title}" -d "&desp=${nowtime}%0D%0A%0D%0A${send_content}" >/dev/null
if [ ! -z "$serverchan_sheep" ] && [ "$serverchan_sheep" -eq "2" ] && [ ! -z "$starttime" ] && [ ! -z "$endtime" ] ;then
if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then
curl -s "http://sc.ftqq.com/$serverchan_sckey.send?text=${send_title}" -d "&desp=${nowtime}%0D%0A%0D%0A${send_content}" >/dev/null
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 当前为免打扰时间,消息不发送" >> ${logfile};fi
fi
else
curl -s "http://sc.ftqq.com/$serverchan_sckey.send?text=${send_title}" -d "&desp=${nowtime}%0D%0A%0D%0A${send_content}" >/dev/null
fi
uci set serverchan.serverchan.send_enable=0
uci commit serverchan
echo "`date "+%H:%M:%S"` 【微信推送】定时发送状态消息" >> ${logfile}
@ -469,10 +568,12 @@ if [ "$1" ] ;then
exit
fi
if [ -z "$serverchan_enable" ] || [ "$serverchan_enable" -eq "0" ] ; then exit;fi
serverchan_init
serverchan_cron
serverchan_disturb
#初始化在线设备列表
function serverchan_first(){
if [ ! -z "$serverchan_enable" ] && [ "$serverchan_enable" -eq "1" ] ; then
@ -512,7 +613,7 @@ if [ ! -z "$serverchan_enable" ] && [ "$serverchan_enable" -eq "1" ] ; then
if ( ! echo $serverchan_whitelist | grep -q -i $ip_mac ); then
up $ip &
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 忽略列表已启用,跳过$ip_name $ip" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 忽略列表已启用,跳过$ip_name $ip" >> ${logfile};fi
fi
# 如果 “关注列表不为空”
@ -520,14 +621,14 @@ if [ ! -z "$serverchan_enable" ] && [ "$serverchan_enable" -eq "1" ] ; then
if ( echo $serverchan_blacklist | grep -q -i $ip_mac ); then
up $ip &
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 关注列表已启用,跳过$ip_name $ip" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 关注列表已启用,跳过$ip_name $ip" >> ${logfile};fi
fi
# 如果 “仅关注接口选项打开”
elif [ ! -z "$serverchan_interface" ] ; then
if ( echo $serverchan_interface | grep -q -i $( cat /proc/net/arp | grep $ip |awk '{print $6}' | grep -v "^$" | sort -u )); then
up $ip &
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 仅关注接口已启用,跳过$ip_name $ip" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 仅关注接口已启用,跳过$ip_name $ip" >> ${logfile};fi
fi
fi
fi
@ -538,6 +639,7 @@ if [ ! -z "$serverchan_enable" ] && [ "$serverchan_enable" -eq "1" ] ; then
fi
}
serverchan_first
usage
while [ "$serverchan_enable" -eq "1" ] ;
do
@ -552,45 +654,88 @@ function rand_geturl(){
rand_geturl
if [ -z "$check" ] || [ "$check" -ne "200" ] ; then sleep 1 && rand_geturl;fi
if [ ! -z "$check" ] && [ "$check" -eq "200" ] ; then
usage
if [ ! -z "$network_enable" ] && [ "$network_enable" -eq "404" ] ; then echo "`date "+%H:%M:%S"` 【网络状态】网络恢复正常.." >> ${logfile};fi
network_enable="200"
#外网IP变化
if [ ! -z "$serverchan_ip" ] && [ "$serverchan_ip" -eq "1" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【外网IP】正在检测外网IP变化" >> ${logfile};fi
if [ ! -z "$serverchan_ipv4" ] && [ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv4" -ne "0" ] || [ "$serverchan_ipv6" -ne "0" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【外网IP】正在检测外网IP变化" >> ${logfile};fi
nowtime=`date "+%Y-%m-%d %H:%M:%S"`
#查询当前ip
#hostIP=$(curl -k -s "http://members.3322.org/dyndns/getip")
wanIP=$(ubus call network.interface.wan status | grep '\"address\"' | grep -oE '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}')
#查询当前 ipv4
if [ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "1" ] ; then IPv4=$(ip -4 address show "$ipv4_interface" | grep inet | grep -v 127.0.0 | awk '{print $2}' | cut -d'/' -f1 | head -n 1 | grep -v "^$" | sort -u);fi
if [ ! -z "$serverchan_ipv4" ] && [ "$serverchan_ipv4" -eq "2" ] ; then IPv4=$(curl -k -s -4 "$ipv4_URL");fi
#查询当前 ipv6
if [ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "1" ] ; then IPv6=$(ip -6 address show "$ipv6_interface" | grep inet6 | awk '{print $2}' | cut -d'/' -f1 | head -n 1 | grep -v "^$" | sort -u);fi
if [ ! -z "$serverchan_ipv6" ] && [ "$serverchan_ipv6" -eq "2" ] ; then IPv6=$(curl -k -s -6 "$ipv6_URL");fi
#查询ip历史记录
if [ -f ${dir}ip ] ; then lastIP=$( cat "${dir}ip");else unset lastIP;fi
if [ ! -z "$lastIP" ] ; then
#if [ "$wanIP" != "$lastIP" ] && [ ! -z "$wanIP" ] ; then
if [ ! -z "$wanIP" ] && ( echo ${wanIP} | grep -w -q ${lastIP} );then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` IP 无变化,当前 ip 为 $lastIP" >> ${logfile};fi
else
echo "`date "+%H:%M:%S"` 当前 IP: ${wanIP}" >> ${logfile}
echo "`date "+%H:%M:%S"` 上次 IP: ${lastIP}" >> ${logfile}
echo "`date "+%H:%M:%S"` 【微信推送】当前IP${wanIP}" >> ${logfile}
echo -n $wanIP > ${dir}ip
if [ -f ${dir}ip ] ; then
last_IPv4=$(cat "${dir}ip" | grep IPv4 | awk '{print $2}' | grep -v "^$" | sort -u)
last_IPv6=$(cat "${dir}ip" | grep IPv6 | awk '{print $2}' | grep -v "^$" | sort -u)
if [ "$serverchan_ipv4" -eq "1" ] ;then
if [ ! -z "$IPv4" ] && ( echo ${IPv4} | grep -w -q ${last_IPv4} );then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` IP 无变化,当前 ip 为 $last_IPv4" >> ${logfile};fi
elif [ ! -z "$IPv4" ] ; then
echo "`date "+%H:%M:%S"` 当前 IP: ${IPv4}" >> ${logfile}
echo "`date "+%H:%M:%S"` 上次 IP: ${last_IPv4}" >> ${logfile}
echo "`date "+%H:%M:%S"` 【微信推送】当前IP${IPv4}" >> ${logfile}
echo IPv4 $IPv4 > ${dir}ip
echo -e IPv6 $last_IPv6 >> ${dir}ip
if [ -f "${dir}title" ] ; then title=`cat ${dir}title` ;fi
if [ -f "${dir}content" ] ; then content=`cat ${dir}content` ;fi
if ( echo ${title} | grep -q "外网IP地址变化" ) || [ -z "$title" ] ; then
title="外网IP地址变化"
if [ -f "${dir}title" ] ; then title=`cat ${dir}title` ;fi
if [ -f "${dir}content" ] ; then content=`cat ${dir}content` ;fi
if ( echo ${title} | grep -q "IP 地址变化" ) || [ -z "$title" ] ; then
title="IP 地址变化"
else
title="设备状态变化"
fi
content="%0D%0A%0D%0A---%0D%0A%0D%0A""####IP 地址变化%0D%0A%0D%0A>当前 IP${IPv4}"
echo $title >${dir}title
echo -n $content >>${dir}content
else
title="设备状态变化"
echo "`date "+%H:%M:%S"` 【!!!】获取 IPv4 地址失败" >> ${logfile}
fi
content="%0D%0A%0D%0A---%0D%0A%0D%0A""####外网IP地址变化%0D%0A%0D%0A>当前IP${wanIP}"
echo $title >${dir}title
echo -n $content >>${dir}content
fi
if [ "$serverchan_ipv6" -eq "1" ] ;then
if [ ! -z "$IPv6" ] && ( echo ${IPv6} | grep -w -q ${last_IPv6} );then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` IPv6 无变化,当前 ipv6 为 $last_IPv6" >> ${logfile};fi
elif [ ! -z "$IPv6" ] ; then
echo "`date "+%H:%M:%S"` 当前 IPv6: ${IPv6}" >> ${logfile}
echo "`date "+%H:%M:%S"` 上次 IPv6: ${last_IPv6}" >> ${logfile}
echo "`date "+%H:%M:%S"` 【微信推送】当前IPv6${IPv6}" >> ${logfile}
echo IPv4 $IPv4 > ${dir}ip
echo -e IPv6 $IPv6 >> ${dir}ip
if [ -f "${dir}title" ] ; then title=`cat ${dir}title` ;fi
if [ -f "${dir}content" ] ; then content=`cat ${dir}content` ;fi
if ( echo ${title} | grep -q "IPv6 地址变化" ) || [ -z "$title" ] ; then
title="IPv6 地址变化"
else
title="设备状态变化"
fi
content="%0D%0A%0D%0A---%0D%0A%0D%0A""####IPv6 地址变化%0D%0A%0D%0A>当前 IPv6${IPv6}"
echo $title >${dir}title
echo -n $content >>${dir}content
else
echo "`date "+%H:%M:%S"` 【!!!】获取 IPv6 地址失败" >> ${logfile}
fi
fi
else
echo "`date "+%H:%M:%S"` 【微信推送】路由器已经重启!当前IP${wanIP}" >> ${logfile}
echo "`date "+%H:%M:%S"` 当前IP: ${wanIP}" >> ${logfile}
echo -n $wanIP > ${dir}ip
unset last_IPv4
unset last_IPv6
echo "`date "+%H:%M:%S"` 【微信推送】路由器已经重启!当前IP${IPv4}" >> ${logfile}
echo "`date "+%H:%M:%S"` 当前IP: ${IPv4}" >> ${logfile}
echo "`date "+%H:%M:%S"` 【微信推送】路由器已经重启!当前IPv6${IPv6}" >> ${logfile}
echo "`date "+%H:%M:%S"` 当前IP: ${IPv6}" >> ${logfile}
echo IPv4 $IPv4 > ${dir}ip
echo -e IPv6 $IPv6 >> ${dir}ip
if [ -f "${dir}title" ] ; then title=`cat ${dir}title` ;fi
if [ -f "${dir}content" ] ; then content=`cat ${dir}content` ;fi
@ -600,7 +745,7 @@ function rand_geturl(){
title="设备状态变化"
fi
content="%0D%0A%0D%0A---%0D%0A%0D%0A""####路由器重新启动%0D%0A%0D%0A>当前IP${wanIP}"
content="%0D%0A%0D%0A---%0D%0A%0D%0A""####路由器重新启动%0D%0A%0D%0A>当前IP${IPv4}%0D%0A%0D%0A---%0D%0A%0D%0A""####IPv6 地址变化%0D%0A%0D%0A>当前 IPv6${IPv6}"
echo $title >${dir}title
echo -n $content >>${dir}content
fi
@ -625,8 +770,10 @@ function rand_geturl(){
ip_name=$( echo "$device_aliases" | grep -i $ip_mac |awk '{print $2}' | grep -v "^$" | sort -u )
ipAddress_name=$( cat ${dir}ipAddress | grep -w $ip | awk '{print $3}' | grep -v "^$" | sort -u )
if [ ! -z ipAddress_name ] && ( ! echo $ip_name | grep -q $ipAddress_name ) ; then
time_up=$( cat ${dir}ipAddress | grep -w $ip |awk '{print $4}' | grep -v "^$" | sort -u )
if [ -z "$time_up" ] ; then time_up=`date +%s`;fi
sed -i "/$ip/d" ${dir}ipAddress
echo "$ip $ip_mac $ip_name" >> ${dir}ipAddress
echo "$ip $ip_mac $ip_name $time_up" >> ${dir}ipAddress
fi
else
ip_name=$( cat /var/dhcp.leases | grep -w $ip |awk '{print $4}' | grep -v "^$" | sort -u )
@ -645,6 +792,7 @@ function rand_geturl(){
down $ip &
else
sed -i "/$ip/d" ${dir}ipAddress
usage_down $ip
fi
# 如果 “关注列表不为空”
@ -653,6 +801,7 @@ function rand_geturl(){
down $ip &
else
sed -i "/$ip/d" ${dir}ipAddress
usage_down $ip
fi
# 如果 “仅关注接口选项打开”
elif [ ! -z "$serverchan_interface" ] ; then
@ -660,6 +809,7 @@ function rand_geturl(){
down $ip &
else
sed -i "/$ip/d" ${dir}ipAddress
usage_down $ip
fi
fi
fi
@ -706,7 +856,7 @@ function rand_geturl(){
if ( ! echo $serverchan_whitelist | grep -q -i $ip_mac ); then
up $ip &
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 忽略列表已启用,跳过$ip_name $ip" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 忽略列表已启用,跳过$ip_name $ip" >> ${logfile};fi
fi
# 如果 “关注列表不为空”
@ -714,7 +864,7 @@ function rand_geturl(){
if ( echo $serverchan_blacklist | grep -q -i $ip_mac ); then
up $ip &
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 关注列表已启用,跳过$ip_name $ip" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 关注列表已启用,跳过$ip_name $ip" >> ${logfile};fi
fi
# 如果 “仅关注接口选项打开”
@ -722,7 +872,7 @@ function rand_geturl(){
if ( echo $serverchan_interface | grep -q -i $( cat /proc/net/arp | grep $ip |awk '{print $6}' | grep -v "^$" | sort -u )); then
up $ip &
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 仅关注接口已启用,跳过$ip_name $ip" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] && ( ! echo ${ip_mac} | grep -q "unknown" ) ; then echo "`date "+%H:%M:%S"` 仅关注接口已启用,跳过$ip_name $ip" >> ${logfile};fi
fi
fi
@ -731,14 +881,16 @@ function rand_geturl(){
wait
if [ -f "${dir}content" ] ; then content=`cat ${dir}content` ;fi
if [ -z "$content" ] || ( ! echo ${content} | grep -q "新设备连接" ) ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 没有新设备连接" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 没有新设备连接" >> ${logfile};fi
else
usage
fi
fi
#负载状态报警
if [ ! -z "$cpuload_enable" ] && [ "$cpuload_enable" -eq "1" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【负载】正在检测 CPU 负载" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【负载】正在检测 CPU 负载" >> ${logfile};fi
cpu_fuzai=`cat /proc/loadavg | awk '{print $1}'`
cpuload=`get_config cpuload`
if [ ! -z "$cpuload" ] && [ `expr $cpu_fuzai \> $cpuload` -eq "1" ] ; then
@ -746,7 +898,7 @@ function rand_geturl(){
echo "`date "+%H:%M:%S"` 【!!警报!!】当前 CPU 负载过高: ${cpu_fuzai}" >> ${logfile}
else
cpuload_n=0
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` CPU 负载正常:$cpu_fuzai" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` CPU 负载正常:$cpu_fuzai" >> ${logfile};fi
fi
if [ "$cpuload_n" -eq "5" ] ;then
@ -764,15 +916,15 @@ function rand_geturl(){
#温度状态报警
if [ ! -z "$temperature_enable" ] && [ "$temperature_enable" -eq "1" ] ; then
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【温度】正在检测 CPU 温度" >> ${logfile};fi
cpu_wendu=`cut -c1-2 /sys/class/thermal/thermal_zone0/temp`
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【温度】正在检测 CPU 温度" >> ${logfile};fi
cpu_wendu=`cut -c1-2 /sys/class/thermal/thermal_zone*/temp`
temperature=`get_config temperature`
if [ ! -z "$temperature" ] && [ "$cpu_wendu" -gt "$temperature" ] ; then
Temperature_n=$(($Temperature_n+1))
echo "`date "+%H:%M:%S"` 【!!警报!!】当前 CPU 温度过高: ${cpu_wendu}" >> ${logfile}
else
Temperature_n=0
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` CPU 温度正常:$cpu_wendu" >> ${logfile};fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` CPU 温度正常:$cpu_wendu" >> ${logfile};fi
fi
if [ "$Temperature_n" -eq "5" ] ;then
if [ -f "${dir}title" ] ; then title=`cat ${dir}title` ;fi
@ -826,9 +978,17 @@ function serverchan_send(){
if [ ! -z "$title" ] && [ ! -z "$content" ] ; then
nowtime=`date "+%Y-%m-%d %H:%M:%S"`
title=$( echo $title | sed $'s/\ /%20/g'| sed $'s/\"/%22/g'| sed $'s/\#/%23/g'| sed $'s/\&/%26/g'| sed $'s/\,/%2C/g'| sed $'s/\//%2F/g'| sed $'s/\:/%3A/g'| sed $'s/\;/%3B/g'| sed $'s/\=/%3D/g'| sed $'s/\@/%40/g')
content=$( echo $content| sed $'s/unknown/%e6%9c%aa%e7%9f%a5%e8%ae%be%e5%a4%87/')
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 进行 URL 编码,标题=$title" >> ${logfile};fi
curl -s "http://sc.ftqq.com/$serverchan_sckey.send?text=${title}" -d "&desp=${nowtime}%0D%0A%0D%0A${content}" >/dev/null
content=$( echo $content| sed $'s/unknown/%e6%9c%aa%e7%9f%a5%e8%ae%be%e5%a4%87/')
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 进行 URL 编码,标题=$title" >> ${logfile};fi
if [ ! -z "$serverchan_sheep" ] && [ "$serverchan_sheep" -eq "2" ] && [ ! -z "$starttime" ] && [ ! -z "$endtime" ] ;then
if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then
curl -s "http://sc.ftqq.com/$serverchan_sckey.send?text=${title}" -d "&desp=${nowtime}%0D%0A%0D%0A${content}" >/dev/null
else
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 当前为免打扰时间,消息不发送" >> ${logfile};fi
fi
else
curl -s "http://sc.ftqq.com/$serverchan_sckey.send?text=${title}" -d "&desp=${nowtime}%0D%0A%0D%0A${content}" >/dev/null
fi
unset title
unset content
rm -f ${dir}title >/dev/null 2>&1
@ -836,18 +996,19 @@ function serverchan_send(){
fi
if [ ! -z "$debuglevel" ] && [ "$debuglevel" -ne "1" ] ; then echo "`date "+%H:%M:%S"` 【等待】我累了,$sleeptime 秒后再回来" >> ${logfile};fi
enable_detection 60
serverchan_disturb
}
serverchan_disturb
serverchan_send
if [ ! -z "$serverchan_sheep" ] && [ "$serverchan_sheep" -eq "1" ] && [ ! -z "$starttime" ] && [ ! -z "$endtime" ] ;then
if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then
serverchan_send
else
serverchan_disturb
fi
else
serverchan_send
fi
#if [ ! -z "$serverchan_sheep" ] && [ "$serverchan_sheep" -eq "1" ] && [ ! -z "$starttime" ] && [ ! -z "$endtime" ] ;then
# if [ `date +%H` -ge $endtime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a $starttime -lt $endtime ] || [ `date +%H` -lt $starttime -a `date +%H` -ge $endtime -a $starttime -gt $endtime ] ; then
# serverchan_send
# else
# serverchan_disturb
# fi
#else
# serverchan_send
#fi
continue
done

View File

@ -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)
}

View File

@ -0,0 +1,302 @@
#!/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
# 提取自 luci-app-wrtbwmon
trap "rm -f /tmp/serverchan/*_$$.tmp; kill $$" INT
binDir=/usr/bin/serverchan/wrtbwmon
dataDir=/tmp/serverchan
lockDir=/tmp/serverchan/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/serverchan/dhcp.leases /tmp/serverchan/dnsmasq.conf /etc/dnsmasq.conf /etc/hosts; do
[ -e "$USERSFILE" ] || continue
case $USERSFILE in
/tmp/serverchan/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/serverchan/*_$$.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/serverchan/iptables_$$.tmp
lock
# only zero our own chains
for chain in $chains; do
iptables -nvxL RRDIPT_$chain -t mangle -Z >> /tmp/serverchan/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/serverchan/iptables_$$.tmp
unlock
}
############################################################
case $1 in
"dump" )
checkDbArg
lock
tr ',' '\t' < "$DB"
unlock
;;
"update" )
checkDbArg
wan=$(detectWAN)
interfaces="$interfaces $wan"
update
rm -f /tmp/serverchan/*_$$.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/serverchan/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/serverchan/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/serverchan/*_$$.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/serverchan/*_$$.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/serverchan/usage.db
$0 update /tmp/serverchan/usage.db
$0 publish /tmp/serverchan/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