From 7b3dece06433e454bc4615dabe71a45e1a52c734 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 3 Apr 2023 16:47:27 +0800 Subject: [PATCH] update 2023-04-03 16:47:27 --- luci-app-adguardhome/README.md | 93 --- luci-app-adguardhome/po/zh_Hans | 1 + .../po/zh_Hans/AdGuardHome.po | 299 -------- .../root/etc/config/AdGuardHome | 0 .../root/etc/init.d/AdGuardHome | 0 .../root/etc/uci-defaults/40_luci-AdGuardHome | 0 .../AdGuardHome/AdGuardHome_template.yaml | 0 .../root/usr/share/AdGuardHome/addhost.sh | 0 .../root/usr/share/AdGuardHome/firewall.start | 0 .../root/usr/share/AdGuardHome/getsyslog.sh | 0 .../root/usr/share/AdGuardHome/gfw2adg.sh | 0 .../root/usr/share/AdGuardHome/links.txt | 0 .../root/usr/share/AdGuardHome/tailto.sh | 0 .../root/usr/share/AdGuardHome/update_core.sh | 0 .../root/usr/share/AdGuardHome/waitnet.sh | 0 .../root/usr/share/AdGuardHome/watchconfig.sh | 0 .../rpcd/acl.d/luci-app-adguardhome.json | 0 .../luasrc/view/admin_network/dev_status.htm | 15 +- oaf/src/af_log.c | 14 +- oaf/src/af_log.h | 3 +- oaf/src/app_filter.c | 42 +- open-app-filter/src/Makefile | 2 +- open-app-filter/src/appfilter.h | 7 + open-app-filter/src/appfilter_config.c | 694 +++++++++--------- open-app-filter/src/appfilter_config.h | 1 + open-app-filter/src/appfilter_user.c | 93 ++- open-app-filter/src/main.c | 328 +++++---- open-app-filter/src/utils.c | 69 ++ open-app-filter/src/utils.h | 6 + 29 files changed, 751 insertions(+), 916 deletions(-) delete mode 100644 luci-app-adguardhome/README.md create mode 120000 luci-app-adguardhome/po/zh_Hans delete mode 100644 luci-app-adguardhome/po/zh_Hans/AdGuardHome.po mode change 100644 => 100755 luci-app-adguardhome/root/etc/config/AdGuardHome mode change 100644 => 100755 luci-app-adguardhome/root/etc/init.d/AdGuardHome mode change 100644 => 100755 luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh mode change 100644 => 100755 luci-app-adguardhome/root/usr/share/rpcd/acl.d/luci-app-adguardhome.json create mode 100755 open-app-filter/src/appfilter.h create mode 100755 open-app-filter/src/utils.c create mode 100755 open-app-filter/src/utils.h diff --git a/luci-app-adguardhome/README.md b/luci-app-adguardhome/README.md deleted file mode 100644 index 3145f8c75..000000000 --- a/luci-app-adguardhome/README.md +++ /dev/null @@ -1,93 +0,0 @@ -# luci-app-adguardhome -复杂的AdGuardHome的openwrt的luci界面 - - - 可以管理网页端口 - - luci下载/更新核心版本(支持自定义链接下载) - - 如果为tar.gz文件需要与官方的文件结构一致 - - 或者直接为主程序二进制 - - upx 压缩核心(xz依赖,脚本自动下载,如果opkg源无法连接,请在编译时加入此包) - - dns重定向 - - 作为dnsmasq的上游服务器(在AGH中统计到的ip都为127.0.0.1,无法统计客户端及对应调整设置,ssr-plus正常) - - 重定向53端口到 AdGuardHome(ipv6需要开启ipv6 nat redirect 否则如果客户端使用ipv6过滤无效,不以dnsmasq为上游ssr-plus失效) - - 使用53端口替换 dnsmasq(需要设置AGH的dnsip为0.0.0.0, AGH和dnsmasq的端口将被交换,不以dnsmasq为上游ssr-plus失效) - - 自定义执行文件路径(支持tmp,每次重启后自动下载bin) - - 自定义配置文件路径 - - 自定义工作路径 - - 自定义运行日志路径 - - gfwlist 删除/添加/定义上游dns服务器 另外安利一下https://github.com/rufengsuixing/luci-app-autoipsetadder - - 修改网页登陆密码 - - 倒序/正序 查看/删除/备份 每3秒更新显示运行日志 + 本地浏览器时区转换 - - 手动修改配置文件 - - 支持yaml编辑器 - - 模板快速配置 - - 系统升级保留勾选文件 - - 开机启动后当网络准备好时重启adh(3分钟超时,主要用于防止过滤器更新失败) - - 关机时备份勾选的工作目录中的文件(须知:在ipk更新的时候也会触发备份) - - 计划任务(以下为默认值,时间和参数可以在计划任务中调整) - - 自动更新核心(最好谨慎使用)(3:30/天) - - 自动截短查询日志 (每小时 限制到2000行) - - 自动截短运行日志(3:30/天 限制到2000行) - - 自动更新ipv6主机并重启adh (每小时,无更新不重启) - - 自动更新gfw列表并重启adh (3:30/天,无更新不重启) -#### 已知问题: - - db数据库不支持放在不支持mmap的文件系统上比如 jffs2 data-stk-oo,请修改工作目录,本软件如果检测到jffs2会自动ln(软连接)到/tmp,将会导致重启丢失dns数据库 - - AdGuardHome 不支持ipset 设置,在使用ipset的情况下,无法替代dnsmasq只能作为dnsmasq上游存在,如果你想要这个功能就去投票吧
- https://github.com/AdguardTeam/AdGuardHome/issues/1191 - - 反馈出现大量127.0.0.1查询了localhost的请求,问题出现原因是ddns插件,如果不用ddns插件,请删除或者注释掉\etc\hotplug.d\iface\95-ddns的内容,如果还有其他来自本机的异常查询情况,高级玩家可以使用kmod来查找原因https://github.com/rufengsuixing/kmod-plog-port - - 如果出现需要多次提交才有反应的现象请及时提交issue -#### 使用方法 - - 下载release,使用opkg安装即可 - - 或者编译op时clone本项目加入软件包并勾选 -#### 关于压缩 -本着较真的想法,我测试了在jffs2的压缩文件系统上进行upx压缩结果的内存占用与空间占用(单位kb,使用最好压缩)
-文件大小
-源文件 14112 使用upx 压缩后 5309
-实际占用 6260 使用upx 压缩后 5324 差值为 936
-VmRSS运存占用值
-不压缩 14380 使用upx 压缩后 18496 差值 -4116
-对于压缩文件系统来说开启收益有,但不大
-如果是非压缩文件系统,性价比还是比较高的
-所以压缩是用运存空间来换rom空间,觉得值得就可以开启 -#### 关于ssr配合 - - 方法一gfw代理:dns重定向-作为dnsmasq的上游服务器 - - 方法二gfw代理:手动设置adh上游dns为自己即127.0.0.1:[自己监听的端口],然后使用 dns重定向-使用53端口替换dnsmasq,(因为端口互换后就是dnsmasq为上游了) - - 方法三国外ip代理:任意重定向方式,adh加入gfw列表,开启计划任务定时更新gfw即可 - - 方法四gfw代理:dns重定向-重定向53端口到AdGuardHome,设置adh上游dns 为127.0.0.1:53 -#### 项目已经基本稳定,有bug欢迎主动反馈 - -Complex openwrt AdGuardHome luci - - - can manage browser port - - download/update core in luci - - compress core with upx - - redirect dns - - as the upstream of dnsmasq - - redirect port 53 to AdGuardHome(ipv6 need to install ipv6 nat redirect or if client use ipv6 redirect is invalid) - - replace dnsmasq with port 53 (need to set AGH,dnsip=0.0.0.0,the port of dnsmasq and AGH will be exchange) - - change bin path - - change config path - - change work dir(support tmp,auto redownload after reboot) - - change runtime log path - - gfwlist query to specific dns server - - modify browser login passord - - Positive/reverse order see/del/backup runtime log which update every 3 second - - modify config manually(support yaml editor) - - use template to fast config(when no config file) - - Keep bin file and config when system upgrade (database and querylog can be choose) - - when boot wait for network access (3min timeout) - - backup workdir when shutdown -#### known issues: - - db database not support filesystem which not support mmap such as jffs2 and data-stk-oo,please modify work dir,if jffs2 is found,will auto ln (soft link)the dbs to /tmp ,will lost dns database after reboot - - AdGuardhome not support ipset,when we use ipset ,it can\`t be the repacement of dnsmasq but the upstream of dnsmasq ,if you want it,vote for it.
- https://github.com/AdguardTeam/AdGuardHome/issues/1191
- - find so many localhost query from 127.0.0.1,the ddns plugin is the reason,if you don\`t use ddns, please remove or comment \etc\hotplug.d\iface\95-ddns -#### usage - - download release,install it with opkg - - or when make op,clone the code to the package path and set it as y or m - -#### pic -example in zh-cn:
-![Screenshot_2019-12-23 newifi-d1 - 基础设置 - LuCI](https://user-images.githubusercontent.com/22387141/71361626-81d60900-25ce-11ea-91d5-ac4e35d5c41e.png) -![图片](https://user-images.githubusercontent.com/22387141/71361650-90242500-25ce-11ea-9727-9306a3da1357.png) -![Screenshot_2019-12-23 newifi-d1 - 日志 - LuCI(1)](https://user-images.githubusercontent.com/22387141/71361700-b944b580-25ce-11ea-8562-f68c28952b2b.png) -![Screenshot_2019-12-23 newifi-d1 - 手动设置 - LuCI](https://user-images.githubusercontent.com/22387141/71361704-bb0e7900-25ce-11ea-8042-6dd396607030.png) diff --git a/luci-app-adguardhome/po/zh_Hans b/luci-app-adguardhome/po/zh_Hans new file mode 120000 index 000000000..41451e4a1 --- /dev/null +++ b/luci-app-adguardhome/po/zh_Hans @@ -0,0 +1 @@ +zh-cn \ No newline at end of file diff --git a/luci-app-adguardhome/po/zh_Hans/AdGuardHome.po b/luci-app-adguardhome/po/zh_Hans/AdGuardHome.po deleted file mode 100644 index 9446fe825..000000000 --- a/luci-app-adguardhome/po/zh_Hans/AdGuardHome.po +++ /dev/null @@ -1,299 +0,0 @@ -#/cgi-bin/luci/admin/services/AdGuardHome -msgid "Base Setting" -msgstr "基础设置" - -msgid "Log" -msgstr "日志" - -msgid "AdGuardHome's version" -msgstr "AdGuardHome 版本" - -msgid "Needed to click 'save&apply' to generate the configuration file" -msgstr "需要点击“保存并应用”才能生成配置文件" - -msgid "In case of the latest realease is a source code that can not download the binary file" -msgstr "防止最新release只有源码,导致下载不成功" - -msgid "Manual Config" -msgstr "手动设置" - -msgid "Free and open source, powerful network-wide ads & trackers blocking DNS server." -msgstr "全网络广告和跟踪程序拦截DNS服务器,默认账号和密码均为:admin" - -msgid "RUNNING" -msgstr "运行中" - -msgid "NOT RUNNING" -msgstr "未运行" - -msgid "Redirected" -msgstr "已重定向" - -msgid "Not redirect" -msgstr "未重定向" - -msgid "Collecting data..." -msgstr "获取数据中..." - -msgid "Enable" -msgstr "启用" - -msgid "Browser management port" -msgstr "网页管理账号和密码:admin ,端口:" - -msgid "Upgrade Core" -msgstr "更新核心" - -#button change -msgid "Update core version" -msgstr "更新核心版本" - -msgid "Check..." -msgstr "检查中..." - -msgid "Updated" -msgstr "已更新" - -#button hide -msgid "Force update" -msgstr "强制更新核心" - -msgid "Fast config" -msgstr "快速配置" - -msgid "Core Version" -msgstr "核心版本" - -msgid "Latest Version" -msgstr "最新版" - -msgid "Beta Version" -msgstr "测试版" - -msgid "Current core version:" -msgstr "当前核心版本:" -msgid "no config" -msgstr "没有配置文件" - -msgid "no core" -msgstr "没有核心" - -# -msgid "Redirect" -msgstr "重定向" - -#inlist -msgid "none" -msgstr "无" - -msgid "Run as dnsmasq upstream server" -msgstr "作为dnsmasq的上游服务器" - -msgid "Redirect 53 port to AdGuardHome" -msgstr "重定向53端口到AdGuardHome" - -msgid "Use port 53 replace dnsmasq" -msgstr "使用53端口替换dnsmasq" - -# -msgid "AdGuardHome redirect mode" -msgstr "AdGuardHome重定向模式" - -msgid "Bin Path" -msgstr "执行文件路径" - -msgid "AdGuardHome Bin path if no bin will auto download" -msgstr "AdGuardHome 执行文件路径 如果没有执行文件将自动下载" - -msgid "use upx to compress bin after download" -msgstr "下载后使用upx压缩执行文件" - -#inlist -msgid "compress faster" -msgstr "快速压缩" - -msgid "compress better" -msgstr "更好的压缩" - -msgid "compress best(can be slow for big files)" -msgstr "最好的压缩(大文件可能慢)" - -msgid "try all available compression methods & filters [slow]" -msgstr "尝试所有可能的压缩方法和过滤器[慢]" - -msgid "try even more compression variants [very slow]" -msgstr "尝试更多变体压缩手段[很慢]" - -msgid "bin use less space,but may have compatibility issues" -msgstr "减小执行文件空间占用,但是可能压缩后有兼容性问题" -# -msgid "Config Path" -msgstr "配置文件路径" - -msgid "AdGuardHome config path" -msgstr "AdGuardHome 配置文件路径" - -msgid "Work dir" -msgstr "工作目录" - -msgid "AdGuardHome work dir include rules,audit log and database" -msgstr "AdGuardHome 工作目录包含规则,审计日志和数据库" - -msgid "Runtime log file" -msgstr "运行日志路径" - -msgid "AdGuardHome runtime Log file if 'syslog': write to system log;if empty no log" -msgstr "AdGuardHome 运行日志, 如果填 syslog 将写入系统日志; 如果该项为空则不记录运行日志" - -msgid "Verbose log" -msgstr "输出详细日志" - -#hide div -msgid "Add gfwlist" -msgstr "添加 GFW 列表" - -msgid "Add" -msgstr "添加" - -msgid "Added" -msgstr "已添加" - -msgid "Not added" -msgstr "未添加" - -#hide div -msgid "Del gfwlist" -msgstr "删除gfw列表" - -msgid "Del" -msgstr "删除" - -#hide div -msgid "Gfwlist upstream dns server" -msgstr "gfw列表上游服务器" - -msgid "Gfwlist domain upstream dns service" -msgstr "gfw列表域名上游服务器" - -#hide div -msgid "Change browser management password" -msgstr "更改网页登录密码" - -msgid "Culculate" -msgstr "计算" - -##button change -msgid "Load culculate model" -msgstr "载入计算模块" - -msgid "loading..." -msgstr "载入中" - -msgid "Please save/apply" -msgstr "请点击[保存/应用]" - -msgid "is empty" -msgstr "为空" - -msgid "Press load culculate model and culculate finally save/apply" -msgstr "先输入你想要的密码, 点击[载入计算模块], 然后点击[计算], 最后点击下方[保存&应用]" - -# -msgid "Keep files when system upgrade" -msgstr "系统升级时保留文件" - -#checkbox -msgid "core bin" -msgstr "核心执行文件" - -msgid "config file" -msgstr "配置文件" - -msgid "log file" -msgstr "日志文件" - -msgid "querylog.json" -msgstr "审计日志.json" - -# -msgid "On boot when network ok restart" -msgstr "开机后网络准备好时重启" - -msgid "Backup workdir files when shutdown" -msgstr "在关机时备份工作目录文件" - -msgid "Will be restore when workdir/data is empty" -msgstr "在工作目录/data为空的时候恢复" - -msgid "Backup workdir path" -msgstr "工作目录备份路径" - -msgid "Crontab task" -msgstr "计划任务" - -msgid "Auto update core" -msgstr "自动升级核心" - -msgid "Auto tail querylog" -msgstr "自动截短查询日志" - -msgid "Auto tail runtime log" -msgstr "自动截短运行日志" - -msgid "Auto update ipv6 hosts and restart adh" -msgstr "自动更新ipv6主机并重启adh" - -msgid "Auto update gfwlist and restart adh" -msgstr "自动更新gfw列表并重启adh" - -msgid "Please change time and args in crontab" -msgstr "请在计划任务中修改时间和参数" - -msgid "Core Update URL" -msgstr "核心更新地址" - -#/cgi-bin/luci/admin/services/AdGuardHome/log/ -msgid "reverse" -msgstr "逆序" - -msgid "localtime" -msgstr "本地时间" - -msgid "Please add log path in config to enable log" -msgstr "请在设置里填写日志路径以启用日志" - -msgid "dellog" -msgstr "删除日志" - -msgid "download log" -msgstr "下载日志" - -#/cgi-bin/luci//admin/services/AdGuardHome/manual/ -msgid "Use template" -msgstr "使用模板" - -#hide button -msgid "Reload Config" -msgstr "重新载入配置" - -msgid "WARNING!!! no bin found apply config will not be test" -msgstr "警告!!!未找到执行文件,提交配置将不会进行校验" - -#unused -msgid "Change browser management username" -msgstr "改变网页登录用户名" - -msgid "Username" -msgstr "用户名" - -msgid "Check Config" -msgstr "检查配置" - -msgid "unknown" -msgstr "未知" - -msgid "Keep database when system upgrade" -msgstr "系统升级时保留数据" - -msgid "Boot delay until network ok" -msgstr "开机时直到网络准备好再启动" \ No newline at end of file diff --git a/luci-app-adguardhome/root/etc/config/AdGuardHome b/luci-app-adguardhome/root/etc/config/AdGuardHome old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/etc/init.d/AdGuardHome b/luci-app-adguardhome/root/etc/init.d/AdGuardHome old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome b/luci-app-adguardhome/root/etc/uci-defaults/40_luci-AdGuardHome old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml b/luci-app-adguardhome/root/usr/share/AdGuardHome/AdGuardHome_template.yaml old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/addhost.sh old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start b/luci-app-adguardhome/root/usr/share/AdGuardHome/firewall.start old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/getsyslog.sh old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/gfw2adg.sh old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt b/luci-app-adguardhome/root/usr/share/AdGuardHome/links.txt old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/tailto.sh old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/update_core.sh old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/waitnet.sh old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh b/luci-app-adguardhome/root/usr/share/AdGuardHome/watchconfig.sh old mode 100644 new mode 100755 diff --git a/luci-app-adguardhome/root/usr/share/rpcd/acl.d/luci-app-adguardhome.json b/luci-app-adguardhome/root/usr/share/rpcd/acl.d/luci-app-adguardhome.json old mode 100644 new mode 100755 diff --git a/luci-app-oaf/luasrc/view/admin_network/dev_status.htm b/luci-app-oaf/luasrc/view/admin_network/dev_status.htm index 0bb46ad37..b7522c958 100755 --- a/luci-app-oaf/luasrc/view/admin_network/dev_status.htm +++ b/luci-app-oaf/luasrc/view/admin_network/dev_status.htm @@ -148,9 +148,15 @@ name: "<%:Visit Time%>", type: 'pie', center: ['35%', '50%'], - radius: ['40%', '65%'], + radius: ['58%', '70%'], clockwise: false, avoidLabelOverlap: false, + itemStyle: { + borderRadius: 2, + borderColor: "#fff", + borderWidth: 1, + }, + label: { normal: { show: true, @@ -249,9 +255,14 @@ name: "<%:Visit Time%>", type: 'pie', center: ['35%', '50%'], - radius: ['40%', '65%'], + radius: ['58%', '70%'], clockwise: false, avoidLabelOverlap: false, + itemStyle: { + borderRadius: 2, + borderColor: "#fff", + borderWidth: 1, + }, label: { normal: { show: true, diff --git a/oaf/src/af_log.c b/oaf/src/af_log.c index 7c6b8b464..cf5aebcd7 100755 --- a/oaf/src/af_log.c +++ b/oaf/src/af_log.c @@ -11,7 +11,8 @@ int af_test_mode = 0; // todo: rename af_log.c int g_oaf_enable __read_mostly = 0; int af_work_mode = AF_MODE_GATEWAY; -int af_lan_ip = 0; +unsigned int af_lan_ip = 0; +unsigned int af_lan_mask = 0; /* cat /proc/sys/oaf/debug */ @@ -47,9 +48,16 @@ static struct ctl_table oaf_table[] = { { .procname = "lan_ip", .data = &af_lan_ip, - .maxlen = sizeof(int), + .maxlen = sizeof(unsigned int), .mode = 0666, - .proc_handler = proc_dointvec, + .proc_handler = proc_douintvec, + }, + { + .procname = "lan_mask", + .data = &af_lan_mask, + .maxlen = sizeof(unsigned int), + .mode = 0666, + .proc_handler = proc_douintvec, }, { } diff --git a/oaf/src/af_log.h b/oaf/src/af_log.h index f05c7bda2..d9380eabc 100755 --- a/oaf/src/af_log.h +++ b/oaf/src/af_log.h @@ -3,7 +3,8 @@ extern int af_log_lvl; extern int af_test_mode; extern int af_work_mode; -extern int af_lan_ip; +extern unsigned int af_lan_ip; +extern unsigned int af_lan_mask; #define LOG(level, fmt, ...) do { \ if ((level) <= af_log_lvl) { \ printk(fmt, ##__VA_ARGS__); \ diff --git a/oaf/src/app_filter.c b/oaf/src/app_filter.c index 70671db00..c27dd235d 100755 --- a/oaf/src/app_filter.c +++ b/oaf/src/app_filter.c @@ -473,6 +473,8 @@ int parse_flow_proto(struct sk_buff *skb, flow_info_t *flow) } return -1; } +#define MAX_HOST_LEN 32 +#define MIN_HOST_LEN 4 int dpi_https_proto(flow_info_t *flow) { @@ -500,12 +502,14 @@ int dpi_https_proto(flow_info_t *flow) { return -1; } + if (p[i] == 0x0 && p[i + 1] == 0x0 && p[i + 2] == 0x0 && p[i + 3] != 0x0) { // 2 bytes memcpy(&url_len, p + i + HTTPS_LEN_OFFSET, 2); - if (ntohs(url_len) <= 0 || ntohs(url_len) > data_len) + + if (ntohs(url_len) <= MIN_HOST_LEN || ntohs(url_len) > data_len || ntohs(url_len) > MAX_HOST_LEN) { continue; } @@ -887,7 +891,29 @@ void af_get_smac(struct sk_buff *skb, u_int8_t *smac){ else memcpy(smac, &skb->cb[40], ETH_ALEN); } +int is_ipv4_broadcast(uint32_t ip) { + return (ip & 0x00FFFFFF) == 0x00FFFFFF; +} + +int is_ipv4_multicast(uint32_t ip) { + return (ip & 0xF0000000) == 0xE0000000; +} +int af_check_bcast_ip(flow_info_t *f) +{ + + if (0 == f->src || 0 == f->dst) + return 1; + if (is_ipv4_broadcast(ntohl(f->src)) || is_ipv4_broadcast(ntohl(f->dst))){ + return 1; + } + if (is_ipv4_multicast(ntohl(f->src)) || is_ipv4_multicast(ntohl(f->dst))){ + return 1; + } + + return 0; +} +#define MAC_FMT "%02X:%02X:%02X:%02X:%02X:%02X" u_int32_t app_filter_hook_bypass_handle(struct sk_buff *skb, struct net_device *dev){ flow_info_t flow; u_int8_t smac[ETH_ALEN]; @@ -896,16 +922,24 @@ u_int32_t app_filter_hook_bypass_handle(struct sk_buff *skb, struct net_device * if (!skb || !dev) return NF_ACCEPT; + if (0 == af_lan_ip || 0 == af_lan_mask) + return NF_ACCEPT; + if (dev->name && strstr(dev->name, "docker")) + return NF_ACCEPT; + memset((char *)&flow, 0x0, sizeof(flow_info_t)); if (parse_flow_proto(skb, &flow) < 0) return NF_ACCEPT; - if (af_match_bcast_packet(&flow) || af_match_local_packet(&flow)) - return NF_ACCEPT; - + if (af_lan_ip == flow.src || af_lan_ip == flow.dst){ return NF_ACCEPT; } + if (af_check_bcast_ip(&flow) || af_match_local_packet(&flow)) + return NF_ACCEPT; + if ((flow.src & af_lan_mask) != (af_lan_ip & af_lan_mask)){ + return NF_ACCEPT; + } af_get_smac(skb, smac); AF_CLIENT_LOCK_W(); diff --git a/open-app-filter/src/Makefile b/open-app-filter/src/Makefile index 3f0cdceff..2236babd5 100755 --- a/open-app-filter/src/Makefile +++ b/open-app-filter/src/Makefile @@ -1,4 +1,4 @@ -OBJS:=appfilter_user.o appfilter_netlink.o appfilter_ubus.o appfilter_config.o main.o +OBJS:=appfilter_user.o appfilter_netlink.o appfilter_ubus.o appfilter_config.o utils.o main.o EXEC:=oafd all: $(OBJS) $(CC) -o $(EXEC) $(OBJS) $(LIBS) diff --git a/open-app-filter/src/appfilter.h b/open-app-filter/src/appfilter.h new file mode 100755 index 000000000..d29163567 --- /dev/null +++ b/open-app-filter/src/appfilter.h @@ -0,0 +1,7 @@ +#ifndef __APPFILTER_H__ +#define __APPFILTER_H__ +#define MIN_INET_ADDR_LEN 7 +#define CMD_GET_LAN_IP "ifconfig br-lan | grep 'inet addr' | awk '{print $2}' | awk -F: '{print $2}'" +#define CMD_GET_LAN_MASK "ifconfig br-lan | grep 'inet addr' | awk '{print $4}' | awk -F: '{print $2}'" + +#endif \ No newline at end of file diff --git a/open-app-filter/src/appfilter_config.c b/open-app-filter/src/appfilter_config.c index 5c464c901..dc219bc05 100755 --- a/open-app-filter/src/appfilter_config.c +++ b/open-app-filter/src/appfilter_config.c @@ -1,342 +1,352 @@ -/* -Copyright (C) 2020 Derry - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ -#include -#include -#include -#include "appfilter_config.h" -#include - -app_name_info_t app_name_table[MAX_SUPPORT_APP_NUM]; -int g_app_count = 0; -int g_cur_class_num = 0; -char CLASS_NAME_TABLE[MAX_APP_TYPE][MAX_CLASS_NAME_LEN]; - -const char *config_path = "./config"; -static struct uci_context *uci_ctx = NULL; -static struct uci_package *uci_appfilter; - - -int uci_get_int_value(struct uci_context *ctx, char *key) -{ - struct uci_element *e; - struct uci_ptr ptr; - int ret = -1; - int dummy; - char *parameters ; - char param_tmp[128] = {0}; - strcpy(param_tmp, key); - if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) { - return ret; - } - - if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) { - ctx->err = UCI_ERR_NOTFOUND; - goto done; - } - - e = ptr.last; - switch(e->type) { - case UCI_TYPE_SECTION: - ret = -1; - goto done; - case UCI_TYPE_OPTION: - ret = atoi(ptr.o->v.string); - goto done; - default: - break; - } -done: - - if (ptr.p) - uci_unload(ctx, ptr.p); - return ret; -} - - -int uci_get_value(struct uci_context *ctx, char *key, char *output, int out_len) -{ - struct uci_element *e; - struct uci_ptr ptr; - int ret = UCI_OK; - int dummy; - char *parameters ; - char param_tmp[128] = {0}; - strcpy(param_tmp, key); - if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) { - ret = 1; - return ret; - } - - if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) { - ctx->err = UCI_ERR_NOTFOUND; - ret = 1; - goto done; - } - - e = ptr.last; - switch(e->type) { - case UCI_TYPE_SECTION: - snprintf(output, out_len, "%s", ptr.s->type); - break; - case UCI_TYPE_OPTION: - snprintf(output, out_len, "%s", ptr.o->v.string); - break; - default: - ret = 1; - break; - } -done: - if (ptr.p) - uci_unload(ctx, ptr.p); - return ret; -} - -// -static struct uci_package * -config_init_package(const char *config) -{ - struct uci_context *ctx = uci_ctx; - struct uci_package *p = NULL; - - if (!ctx) - { - ctx = uci_alloc_context(); - uci_ctx = ctx; - ctx->flags &= ~UCI_FLAG_STRICT; - //if (config_path) - // uci_set_confdir(ctx, config_path); - } - else - { - p = uci_lookup_package(ctx, config); - if (p) - uci_unload(ctx, p); - } - - if (uci_load(ctx, config, &p)) - return NULL; - - return p; -} -char *get_app_name_by_id(int id) -{ - int i; - for (i = 0; i < g_app_count; i++) - { - if (id == app_name_table[i].id) - return app_name_table[i].name; - } - return ""; -} - -void init_app_name_table(void) -{ - int count = 0; - char line_buf[2048] = {0}; - - FILE *fp = fopen("/tmp/feature.cfg", "r"); - if (!fp) - { - printf("open file failed\n"); - return; - } - - while (fgets(line_buf, sizeof(line_buf), fp)) - { - if (strstr(line_buf, "#")) - continue; - if (strlen(line_buf) < 10) - continue; - if (!strstr(line_buf, ":")) - continue; - char *pos1 = strstr(line_buf, ":"); - char app_info_buf[128] = {0}; - int app_id; - char app_name[64] = {0}; - memset(app_name, 0x0, sizeof(app_name)); - strncpy(app_info_buf, line_buf, pos1 - line_buf); - sscanf(app_info_buf, "%d %s", &app_id, app_name); - app_name_table[g_app_count].id = app_id; - strcpy(app_name_table[g_app_count].name, app_name); - g_app_count++; - } - fclose(fp); -} - -void init_app_class_name_table(void) -{ - char line_buf[2048] = {0}; - int class_id; - char class_name[64] = {0}; - FILE *fp = fopen("/tmp/app_class.txt", "r"); - if (!fp) - { - printf("open file failed\n"); - return; - } - while (fgets(line_buf, sizeof(line_buf), fp)) - { - sscanf(line_buf, "%d %*s %s", &class_id, class_name); - printf("line buf = %s, class_name = %s\n", line_buf, class_name); - strcpy(CLASS_NAME_TABLE[class_id - 1], class_name); - g_cur_class_num++; - } - fclose(fp); -} -//00:00 9:1 -int check_time_valid(char *t) -{ - if (!t) - return 0; - if (strlen(t) < 3 || strlen(t) > 5 || (!strstr(t, ":"))) - return 0; - else - return 1; -} - -void dump_af_time(af_ctl_time_t *t) -{ - int i; - printf("---------dump af time-------------\n"); - printf("%d:%d ---->%d:%d\n", t->start.hour, t->start.min, - t->end.hour, t->end.min); - for (i = 0; i < 7; i++) - { - printf("%d ", t->days[i]); - } - printf("\n"); -} - -af_ctl_time_t *load_appfilter_ctl_time_config(void) -{ - char start_time_str[64] = {0}; - char end_time_str[64] = {0}; - char start_time_str2[64] = {0}; - char end_time_str2[64] = {0}; - char days_str[64] = {0}; - int value = 0; - int ret = 0; - af_ctl_time_t *t = NULL; - struct uci_context *ctx = uci_alloc_context(); - if (!ctx) - return NULL; - - memset(start_time_str, 0x0, sizeof(start_time_str)); - memset(end_time_str, 0x0, sizeof(end_time_str)); - memset(start_time_str2, 0x0, sizeof(start_time_str2)); - memset(end_time_str2, 0x0, sizeof(end_time_str2)); - - uci_get_value(ctx, "appfilter.time.start_time", start_time_str, sizeof(start_time_str)); - uci_get_value(ctx, "appfilter.time.end_time", end_time_str, sizeof(end_time_str)); - uci_get_value(ctx, "appfilter.time.start_time2", start_time_str2, sizeof(start_time_str2)); - uci_get_value(ctx, "appfilter.time.end_time2", end_time_str2, sizeof(end_time_str2)); - uci_get_value(ctx, "appfilter.time.days", days_str, sizeof(days_str)); - - - t = malloc(sizeof(af_ctl_time_t)); - - value = uci_get_int_value(ctx, "appfilter.time.time_mode"); - if (value < 0) - t->time_mode = 0; - else - t->time_mode = value; - if (check_time_valid(start_time_str) && check_time_valid(end_time_str)){ - sscanf(start_time_str, "%d:%d", &t->start.hour, &t->start.min); - sscanf(end_time_str, "%d:%d", &t->end.hour, &t->end.min); - } - if (check_time_valid(start_time_str2) && check_time_valid(end_time_str2)){ - sscanf(start_time_str2, "%d:%d", &t->start2.hour, &t->start2.min); - sscanf(end_time_str2, "%d:%d", &t->end2.hour, &t->end2.min); - } - - char *p = strtok(days_str, " "); - if (!p) - goto EXIT; - do - { - int day = atoi(p); - if (day >= 0 && day <= 6) - t->days[day] = 1; - else - ret = 0; - } while (p = strtok(NULL, " ")); -EXIT: - uci_free_context(ctx); - return t; -} - - - -int config_get_appfilter_enable(void) -{ - int enable = 0; - struct uci_context *ctx = uci_alloc_context(); - if (!ctx) - return NULL; - enable = uci_get_int_value(ctx, "appfilter.global.enable"); - if (enable < 0) - enable = 0; - - uci_free_context(ctx); - return enable; -} - -int config_get_lan_ip(char *lan_ip, int len) -{ - int ret = 0; - struct uci_context *ctx = uci_alloc_context(); - if (!ctx) - return -1; - ret = uci_get_value(ctx, "network.lan.ipaddr", lan_ip, len); - uci_free_context(ctx); - return ret; -} - - -int appfilter_config_alloc(void) -{ - char *err; - uci_appfilter = config_init_package("appfilter"); - if (!uci_appfilter) - { - uci_get_errorstr(uci_ctx, &err, NULL); - printf("Failed to load appfilter config (%s)\n", err); - free(err); - return -1; - } - - return 0; -} - -int appfilter_config_free(void) -{ - if (uci_appfilter) - { - uci_unload(uci_ctx, uci_appfilter); - uci_appfilter = NULL; - } - if (uci_ctx) - { - uci_free_context(uci_ctx); - uci_ctx = NULL; - } -} +/* +Copyright (C) 2020 Derry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#include +#include +#include +#include "appfilter_config.h" +#include + +app_name_info_t app_name_table[MAX_SUPPORT_APP_NUM]; +int g_app_count = 0; +int g_cur_class_num = 0; +char CLASS_NAME_TABLE[MAX_APP_TYPE][MAX_CLASS_NAME_LEN]; + +const char *config_path = "./config"; +static struct uci_context *uci_ctx = NULL; +static struct uci_package *uci_appfilter; + + +int uci_get_int_value(struct uci_context *ctx, char *key) +{ + struct uci_element *e; + struct uci_ptr ptr; + int ret = -1; + int dummy; + char *parameters ; + char param_tmp[128] = {0}; + strcpy(param_tmp, key); + if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) { + return ret; + } + + if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) { + ctx->err = UCI_ERR_NOTFOUND; + goto done; + } + + e = ptr.last; + switch(e->type) { + case UCI_TYPE_SECTION: + ret = -1; + goto done; + case UCI_TYPE_OPTION: + ret = atoi(ptr.o->v.string); + goto done; + default: + break; + } +done: + + if (ptr.p) + uci_unload(ctx, ptr.p); + return ret; +} + + +int uci_get_value(struct uci_context *ctx, char *key, char *output, int out_len) +{ + struct uci_element *e; + struct uci_ptr ptr; + int ret = UCI_OK; + int dummy; + char *parameters ; + char param_tmp[128] = {0}; + strcpy(param_tmp, key); + if (uci_lookup_ptr(ctx, &ptr, param_tmp, true) != UCI_OK) { + ret = 1; + return ret; + } + + if (!(ptr.flags & UCI_LOOKUP_COMPLETE)) { + ctx->err = UCI_ERR_NOTFOUND; + ret = 1; + goto done; + } + + e = ptr.last; + switch(e->type) { + case UCI_TYPE_SECTION: + snprintf(output, out_len, "%s", ptr.s->type); + break; + case UCI_TYPE_OPTION: + snprintf(output, out_len, "%s", ptr.o->v.string); + break; + default: + ret = 1; + break; + } +done: + if (ptr.p) + uci_unload(ctx, ptr.p); + return ret; +} + +// +static struct uci_package * +config_init_package(const char *config) +{ + struct uci_context *ctx = uci_ctx; + struct uci_package *p = NULL; + + if (!ctx) + { + ctx = uci_alloc_context(); + uci_ctx = ctx; + ctx->flags &= ~UCI_FLAG_STRICT; + //if (config_path) + // uci_set_confdir(ctx, config_path); + } + else + { + p = uci_lookup_package(ctx, config); + if (p) + uci_unload(ctx, p); + } + + if (uci_load(ctx, config, &p)) + return NULL; + + return p; +} +char *get_app_name_by_id(int id) +{ + int i; + for (i = 0; i < g_app_count; i++) + { + if (id == app_name_table[i].id) + return app_name_table[i].name; + } + return ""; +} + +void init_app_name_table(void) +{ + int count = 0; + char line_buf[2048] = {0}; + + FILE *fp = fopen("/tmp/feature.cfg", "r"); + if (!fp) + { + printf("open file failed\n"); + return; + } + + while (fgets(line_buf, sizeof(line_buf), fp)) + { + if (strstr(line_buf, "#")) + continue; + if (strlen(line_buf) < 10) + continue; + if (!strstr(line_buf, ":")) + continue; + char *pos1 = strstr(line_buf, ":"); + char app_info_buf[128] = {0}; + int app_id; + char app_name[64] = {0}; + memset(app_name, 0x0, sizeof(app_name)); + strncpy(app_info_buf, line_buf, pos1 - line_buf); + sscanf(app_info_buf, "%d %s", &app_id, app_name); + app_name_table[g_app_count].id = app_id; + strcpy(app_name_table[g_app_count].name, app_name); + g_app_count++; + } + fclose(fp); +} + +void init_app_class_name_table(void) +{ + char line_buf[2048] = {0}; + int class_id; + char class_name[64] = {0}; + FILE *fp = fopen("/tmp/app_class.txt", "r"); + if (!fp) + { + printf("open file failed\n"); + return; + } + while (fgets(line_buf, sizeof(line_buf), fp)) + { + sscanf(line_buf, "%d %*s %s", &class_id, class_name); + strcpy(CLASS_NAME_TABLE[class_id - 1], class_name); + g_cur_class_num++; + } + fclose(fp); +} +//00:00 9:1 +int check_time_valid(char *t) +{ + if (!t) + return 0; + if (strlen(t) < 3 || strlen(t) > 5 || (!strstr(t, ":"))) + return 0; + else + return 1; +} + +void dump_af_time(af_ctl_time_t *t) +{ + int i; + printf("---------dump af time-------------\n"); + printf("%d:%d ---->%d:%d\n", t->start.hour, t->start.min, + t->end.hour, t->end.min); + for (i = 0; i < 7; i++) + { + printf("%d ", t->days[i]); + } + printf("\n"); +} + +af_ctl_time_t *load_appfilter_ctl_time_config(void) +{ + char start_time_str[64] = {0}; + char end_time_str[64] = {0}; + char start_time_str2[64] = {0}; + char end_time_str2[64] = {0}; + char days_str[64] = {0}; + int value = 0; + int ret = 0; + af_ctl_time_t *t = NULL; + struct uci_context *ctx = uci_alloc_context(); + if (!ctx) + return NULL; + + memset(start_time_str, 0x0, sizeof(start_time_str)); + memset(end_time_str, 0x0, sizeof(end_time_str)); + memset(start_time_str2, 0x0, sizeof(start_time_str2)); + memset(end_time_str2, 0x0, sizeof(end_time_str2)); + + uci_get_value(ctx, "appfilter.time.start_time", start_time_str, sizeof(start_time_str)); + uci_get_value(ctx, "appfilter.time.end_time", end_time_str, sizeof(end_time_str)); + uci_get_value(ctx, "appfilter.time.start_time2", start_time_str2, sizeof(start_time_str2)); + uci_get_value(ctx, "appfilter.time.end_time2", end_time_str2, sizeof(end_time_str2)); + uci_get_value(ctx, "appfilter.time.days", days_str, sizeof(days_str)); + + + t = malloc(sizeof(af_ctl_time_t)); + + value = uci_get_int_value(ctx, "appfilter.time.time_mode"); + if (value < 0) + t->time_mode = 0; + else + t->time_mode = value; + if (check_time_valid(start_time_str) && check_time_valid(end_time_str)){ + sscanf(start_time_str, "%d:%d", &t->start.hour, &t->start.min); + sscanf(end_time_str, "%d:%d", &t->end.hour, &t->end.min); + } + if (check_time_valid(start_time_str2) && check_time_valid(end_time_str2)){ + sscanf(start_time_str2, "%d:%d", &t->start2.hour, &t->start2.min); + sscanf(end_time_str2, "%d:%d", &t->end2.hour, &t->end2.min); + } + + char *p = strtok(days_str, " "); + if (!p) + goto EXIT; + do + { + int day = atoi(p); + if (day >= 0 && day <= 6) + t->days[day] = 1; + else + ret = 0; + } while (p = strtok(NULL, " ")); +EXIT: + uci_free_context(ctx); + return t; +} + + + +int config_get_appfilter_enable(void) +{ + int enable = 0; + struct uci_context *ctx = uci_alloc_context(); + if (!ctx) + return NULL; + enable = uci_get_int_value(ctx, "appfilter.global.enable"); + if (enable < 0) + enable = 0; + + uci_free_context(ctx); + return enable; +} + +int config_get_lan_ip(char *lan_ip, int len) +{ + int ret = 0; + struct uci_context *ctx = uci_alloc_context(); + if (!ctx) + return -1; + ret = uci_get_value(ctx, "network.lan.ipaddr", lan_ip, len); + uci_free_context(ctx); + return ret; +} + +int config_get_lan_mask(char *lan_mask, int len) +{ + int ret = 0; + struct uci_context *ctx = uci_alloc_context(); + if (!ctx) + return -1; + ret = uci_get_value(ctx, "network.lan.netmask", lan_mask, len); + uci_free_context(ctx); + return ret; +} + + +int appfilter_config_alloc(void) +{ + char *err; + uci_appfilter = config_init_package("appfilter"); + if (!uci_appfilter) + { + uci_get_errorstr(uci_ctx, &err, NULL); + printf("Failed to load appfilter config (%s)\n", err); + free(err); + return -1; + } + + return 0; +} + +int appfilter_config_free(void) +{ + if (uci_appfilter) + { + uci_unload(uci_ctx, uci_appfilter); + uci_appfilter = NULL; + } + if (uci_ctx) + { + uci_free_context(uci_ctx); + uci_ctx = NULL; + } +} diff --git a/open-app-filter/src/appfilter_config.h b/open-app-filter/src/appfilter_config.h index e2770c375..4a29d3b78 100755 --- a/open-app-filter/src/appfilter_config.h +++ b/open-app-filter/src/appfilter_config.h @@ -57,5 +57,6 @@ int appfilter_config_free(void); af_ctl_time_t *load_appfilter_ctl_time_config(void); int config_get_appfilter_enable(void); int config_get_lan_ip(char *lan_ip, int len); +int config_get_lan_mask(char *lan_mask, int len); #endif diff --git a/open-app-filter/src/appfilter_user.c b/open-app-filter/src/appfilter_user.c index 6b1e2170f..6a5c4a9a7 100755 --- a/open-app-filter/src/appfilter_user.c +++ b/open-app-filter/src/appfilter_user.c @@ -29,6 +29,7 @@ THE SOFTWARE. #include #include #include +#include "appfilter.h" #include "appfilter_user.h" dev_node_t *dev_hash_table[MAX_DEV_NODE_HASH_SIZE]; @@ -190,7 +191,8 @@ void clean_dev_online_status(void) dev_node_t *node = dev_hash_table[i]; while (node) { - if (node->online){ + if (node->online) + { node->offline_time = get_timestamp(); node->online = 0; } @@ -200,10 +202,10 @@ void clean_dev_online_status(void) } /* -Id Mac Ip -1 10:bf:48:37:0c:94 192.168.66.244 +Id Mac Ip +1 10:bf:48:37:0c:94 192.168.66.244 */ -void update_dev_online_status(void) +void update_dev_from_oaf(void) { char line_buf[256] = {0}; char mac_buf[32] = {0}; @@ -237,6 +239,59 @@ void update_dev_online_status(void) fclose(fp); } +void update_dev_from_arp(void) +{ + char line_buf[256] = {0}; + char mac_buf[32] = {0}; + char ip_buf[32] = {0}; + char lan_ip[32] = {0}; + char lan_mask[32] = {0}; + + exec_with_result_line(CMD_GET_LAN_IP, lan_ip, sizeof(lan_ip)); + exec_with_result_line(CMD_GET_LAN_MASK, lan_mask, sizeof(lan_mask)); + if (strlen(lan_ip) < MIN_INET_ADDR_LEN || strlen(lan_mask) < MIN_INET_ADDR_LEN) + { + return; + } + + FILE *fp = fopen("/proc/net/arp", "r"); + if (!fp) + { + printf("open dev file....failed\n"); + return; + } + fgets(line_buf, sizeof(line_buf), fp); // title + while (fgets(line_buf, sizeof(line_buf), fp)) + { + sscanf(line_buf, "%s %*s %*s %s", ip_buf, mac_buf); + + if (strlen(mac_buf) < 17 || strlen(ip_buf) < MIN_INET_ADDR_LEN) + { + printf("invalid mac:%s or ip:%s\n", mac_buf, ip_buf); + continue; + } + if (0 == strcmp(mac_buf, "00:00:00:00:00:00")) + continue; + if (!check_same_network(lan_ip, lan_mask, ip_buf) || 0 == strcmp(lan_ip, ip_buf)) + { + continue; + } + dev_node_t *node = find_dev_node(mac_buf); + if (!node) + { + node = add_dev_node(mac_buf); + if (!node) + continue; + strncpy(node->ip, ip_buf, sizeof(node->ip)); + } + } + fclose(fp); +} +void update_dev_online_status(void) +{ + update_dev_from_oaf(); + update_dev_from_arp(); +} #define DEV_OFFLINE_TIME (SECONDS_PER_DAY * 3) @@ -272,7 +327,7 @@ int check_dev_expire(void) } expire_count++; printf("dev:%s expired, offline time = %ds, count=%d, visit_count=%d\n", - node->mac, offline_time, expire_count, visit_count); + node->mac, offline_time, expire_count, visit_count); } NEXT: node = node->next; @@ -389,10 +444,10 @@ EXIT: fclose(fp); } // 记录最大保存时间 todo: support config -#define MAX_RECORD_TIME (7 * 24 * 60 * 60) // 7day +#define MAX_RECORD_TIME (3 * 24 * 60 * 60) // 7day // 超过1天后清除短时间的记录 #define RECORD_REMAIN_TIME (24 * 60 * 60) // 1day -#define INVALID_RECORD_TIME (5 * 60) // 5min +#define INVALID_RECORD_TIME (5 * 60) // 5min void check_dev_visit_info_expire(void) { @@ -410,11 +465,13 @@ void check_dev_visit_info_expire(void) while (p_info) { int total_time = p_info->latest_time - p_info->first_time; - int interval_time = cur_time - p_info->first_time; - if (interval_time > MAX_RECORD_TIME || interval_time < 0){ + int interval_time = cur_time - p_info->first_time; + if (interval_time > MAX_RECORD_TIME || interval_time < 0) + { p_info->expire = 1; } - else if (interval_time > RECORD_REMAIN_TIME){ + else if (interval_time > RECORD_REMAIN_TIME) + { if (total_time < INVALID_RECORD_TIME) p_info->expire = 1; } @@ -442,24 +499,27 @@ void flush_expire_visit_info(void) prev = NULL; while (p_info) { - if (p_info->expire){ - if (NULL == prev){ + if (p_info->expire) + { + if (NULL == prev) + { node->visit_htable[j] = p_info->next; free(p_info); p_info = node->visit_htable[j]; prev = NULL; } - else{ + else + { prev->next = p_info->next; free(p_info); p_info = prev->next; } } - else{ + else + { prev = p_info; p_info = p_info->next; } - } } node = node->next; @@ -467,9 +527,6 @@ void flush_expire_visit_info(void) } } - - - void dump_dev_visit_list(void) { int i, j; diff --git a/open-app-filter/src/main.c b/open-app-filter/src/main.c index a506b0f8b..4532f52aa 100755 --- a/open-app-filter/src/main.c +++ b/open-app-filter/src/main.c @@ -1,153 +1,175 @@ -/* -Copyright (C) 2020 Derry - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN -THE SOFTWARE. -*/ -#include -#include -#include -#include -#include -#include -#include "appfilter_user.h" -#include "appfilter_netlink.h" -#include "appfilter_ubus.h" -#include "appfilter_config.h" -#include -#include -#include -void check_appfilter_enable(void) -{ - int enable = 1; - struct tm *t; - af_ctl_time_t *af_t = NULL; - time_t tt; - time(&tt); - enable = config_get_appfilter_enable(); - - if (0 == enable) - goto EXIT; - af_t = load_appfilter_ctl_time_config(); - if (!af_t) - { - enable = 0; - goto EXIT; - } - - t = localtime(&tt); - if (af_t->days[t->tm_wday] != 1) - { - if (af_t->time_mode == 0){ - enable = 0; - goto EXIT; - } - } - - int cur_mins = t->tm_hour * 60 + t->tm_min; - if (((af_t->start.hour * 60 + af_t->start.min < cur_mins) && (cur_mins < af_t->end.hour * 60 + af_t->end.min)) - || ((af_t->start2.hour * 60 + af_t->start2.min < cur_mins) && (cur_mins < af_t->end2.hour * 60 + af_t->end2.min)) - ) - { - if (af_t->time_mode == 0){ - enable = 1; - } - else{ - enable = 0; - } - } - else{ - if (af_t->time_mode == 0){ - enable = 0; - } - else{ - enable = 1; - } - } -EXIT: - if (enable) - { - system("echo 1 >/proc/sys/oaf/enable "); - } - else - system("echo 0 >/proc/sys/oaf/enable "); - if (af_t) - free(af_t); -} - -void update_lan_ip(void){ - char ip_str[32] = {0}; - struct in_addr addr; - char cmd_buf[128] = {0}; - u_int32_t lan_ip = 0; - - config_get_lan_ip(ip_str, sizeof(ip_str)); - inet_aton(ip_str, &addr); - lan_ip =addr.s_addr; - sprintf(cmd_buf, "echo %d >/proc/sys/oaf/lan_ip", lan_ip); - system(cmd_buf); -} - -void dev_list_timeout_handler(struct uloop_timeout *t) -{ - dump_dev_list(); - check_dev_visit_info_expire(); - flush_expire_visit_info(); - //dump_dev_visit_list(); - update_lan_ip(); - check_appfilter_enable(); - if (check_dev_expire()){ - flush_expire_visit_info(); - flush_dev_expire_node(); - } - uloop_timeout_set(t, 10000); -} - -struct uloop_timeout dev_tm = { - .cb = dev_list_timeout_handler}; - -static struct uloop_fd appfilter_nl_fd = { - .cb = appfilter_nl_handler, -}; - -int main(int argc, char **argv) -{ - int ret = 0; - uloop_init(); - printf("init appfilter\n"); - init_dev_node_htable(); - init_app_name_table(); - init_app_class_name_table(); - if (appfilter_ubus_init() < 0) - { - fprintf(stderr, "Failed to connect to ubus\n"); - return 1; - } - - - appfilter_nl_fd.fd = appfilter_nl_init(); - uloop_fd_add(&appfilter_nl_fd, ULOOP_READ); - af_msg_t msg; - msg.action = AF_MSG_INIT; - send_msg_to_kernel(appfilter_nl_fd.fd, (void *)&msg, sizeof(msg)); - uloop_timeout_set(&dev_tm, 5000); - uloop_timeout_add(&dev_tm); - uloop_run(); - uloop_done(); - return 0; -} +/* +Copyright (C) 2020 Derry + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. +*/ +#include +#include +#include +#include +#include +#include +#include "appfilter_user.h" +#include "appfilter_netlink.h" +#include "appfilter_ubus.h" +#include "appfilter_config.h" +#include +#include +#include +#include "appfilter.h" + + +void check_appfilter_enable(void) +{ + int enable = 1; + struct tm *t; + af_ctl_time_t *af_t = NULL; + time_t tt; + time(&tt); + enable = config_get_appfilter_enable(); + + if (0 == enable) + goto EXIT; + af_t = load_appfilter_ctl_time_config(); + if (!af_t) + { + enable = 0; + goto EXIT; + } + + t = localtime(&tt); + if (af_t->days[t->tm_wday] != 1) + { + if (af_t->time_mode == 0){ + enable = 0; + goto EXIT; + } + } + + int cur_mins = t->tm_hour * 60 + t->tm_min; + if (((af_t->start.hour * 60 + af_t->start.min < cur_mins) && (cur_mins < af_t->end.hour * 60 + af_t->end.min)) + || ((af_t->start2.hour * 60 + af_t->start2.min < cur_mins) && (cur_mins < af_t->end2.hour * 60 + af_t->end2.min)) + ) + { + if (af_t->time_mode == 0){ + enable = 1; + } + else{ + enable = 0; + } + } + else{ + if (af_t->time_mode == 0){ + enable = 0; + } + else{ + enable = 1; + } + } +EXIT: + if (enable) + { + system("echo 1 >/proc/sys/oaf/enable "); + } + else + system("echo 0 >/proc/sys/oaf/enable "); + if (af_t) + free(af_t); +} + +void update_lan_ip(void){ + char ip_str[32] = {0}; + char mask_str[32] = {0}; + struct in_addr addr; + struct in_addr mask_addr; + char cmd_buf[128] = {0}; + u_int32_t lan_ip = 0; + u_int32_t lan_mask = 0; + + exec_with_result_line(CMD_GET_LAN_IP, ip_str, sizeof(ip_str)); + if (strlen(ip_str) < MIN_INET_ADDR_LEN){ + sprintf(cmd_buf, "echo 0 >/proc/sys/oaf/lan_ip"); + } + else{ + inet_aton(ip_str, &addr); + lan_ip = addr.s_addr; + sprintf(cmd_buf, "echo %u >/proc/sys/oaf/lan_ip", lan_ip); + } + system(cmd_buf); + exec_with_result_line(CMD_GET_LAN_MASK, mask_str, sizeof(mask_str)); + + if (strlen(mask_str) < MIN_INET_ADDR_LEN){ + sprintf(cmd_buf, "echo 0 >/proc/sys/oaf/lan_mask"); + } + else{ + inet_aton(mask_str, &mask_addr); + lan_mask = mask_addr.s_addr; + sprintf(cmd_buf, "echo %u >/proc/sys/oaf/lan_mask", lan_mask); + } + system(cmd_buf); +} + +void dev_list_timeout_handler(struct uloop_timeout *t) +{ + dump_dev_list(); + check_dev_visit_info_expire(); + flush_expire_visit_info(); + //dump_dev_visit_list(); + update_lan_ip(); + check_appfilter_enable(); + if (check_dev_expire()){ + flush_expire_visit_info(); + flush_dev_expire_node(); + } + uloop_timeout_set(t, 10000); +} + +struct uloop_timeout dev_tm = { + .cb = dev_list_timeout_handler}; + +static struct uloop_fd appfilter_nl_fd = { + .cb = appfilter_nl_handler, +}; + +int main(int argc, char **argv) +{ + int ret = 0; + uloop_init(); + printf("init appfilter\n"); + init_dev_node_htable(); + init_app_name_table(); + init_app_class_name_table(); + if (appfilter_ubus_init() < 0) + { + fprintf(stderr, "Failed to connect to ubus\n"); + return 1; + } + + + appfilter_nl_fd.fd = appfilter_nl_init(); + uloop_fd_add(&appfilter_nl_fd, ULOOP_READ); + af_msg_t msg; + msg.action = AF_MSG_INIT; + send_msg_to_kernel(appfilter_nl_fd.fd, (void *)&msg, sizeof(msg)); + uloop_timeout_set(&dev_tm, 5000); + uloop_timeout_add(&dev_tm); + uloop_run(); + uloop_done(); + return 0; +} diff --git a/open-app-filter/src/utils.c b/open-app-filter/src/utils.c new file mode 100755 index 000000000..7b0463f96 --- /dev/null +++ b/open-app-filter/src/utils.c @@ -0,0 +1,69 @@ + +#include +#include +#include +#include + + +char *str_trim(char *s) { + char *start, *last, *bk; + int len; + + start = s; + while (isspace(*start)) + start++; + + bk = last = s + strlen(s) - 1; + while (last > start && isspace(*last)) + last--; + + if ((s != start) || (bk != last)) { + len = last - start + 1; + strncpy(s, start, len); + s[len] = '\0'; + } + return s; +} + +int exec_with_result_line(char *cmd, char *result, int len) +{ + FILE *fp = NULL; + if (!cmd || !result || !len) + return -1; + fp = popen(cmd, "r"); + if (!fp) + return -1; + fgets(result, len, fp); + str_trim(result); + pclose(fp); + return 0; +} + + +#include +#include +#include +#include + +int check_same_network(char *ip1, char *netmask, char *ip2) { + struct in_addr addr1, addr2, mask; + + if (inet_pton(AF_INET, ip1, &addr1) != 1) { + printf("Invalid IP address: %s\n", ip1); + return -1; + } + if (inet_pton(AF_INET, netmask, &mask) != 1) { + printf("Invalid netmask: %s\n", netmask); + return -1; + } + if (inet_pton(AF_INET, ip2, &addr2) != 1) { + printf("Invalid IP address: %s\n", ip2); + return -1; + } + + if ((addr1.s_addr & mask.s_addr) == (addr2.s_addr & mask.s_addr)) { + return 1; + } else { + return 0; + } +} diff --git a/open-app-filter/src/utils.h b/open-app-filter/src/utils.h new file mode 100755 index 000000000..7c5d4fdb2 --- /dev/null +++ b/open-app-filter/src/utils.h @@ -0,0 +1,6 @@ +#ifndef __UTILS_H__ +#define __UTILS_H__ +char *str_trim(char *s); +int exec_with_result_line(char *cmd, char *result, int len); +int check_same_network(char *ip1, char *netmask, char *ip2); +#endif \ No newline at end of file