mirror of
https://github.com/kiddin9/openwrt-packages.git
synced 2025-01-09 06:07:44 +08:00
update
This commit is contained in:
parent
b045da7985
commit
1d42fd874d
63
MentoHUST-OpenWrt-ipk/Makefile
Normal file
63
MentoHUST-OpenWrt-ipk/Makefile
Normal file
@ -0,0 +1,63 @@
|
||||
#
|
||||
# Copyright (C) 2014-2015 KyleRicardo
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=mentohust
|
||||
PKG_VERSION:=0.3.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/mentohust
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libpcap
|
||||
TITLE:=A Ruijie Client Daemon
|
||||
URL:=https://github.com/KyleRicardo/MentoHUST-OpenWrt-ipk.git
|
||||
SUBMENU:=Ruijie
|
||||
endef
|
||||
|
||||
define Package/mentohust/description
|
||||
A Ruijie Client Daemon,
|
||||
Most usually used in China collages.
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) ./src/* $(PKG_BUILD_DIR)/
|
||||
$(SED) 's/dhclient/udhcpc -i/g' $(PKG_BUILD_DIR)/myconfig.c
|
||||
endef
|
||||
|
||||
|
||||
define Package/mentohust/conffiles
|
||||
/etc/mentohust.conf
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
#$(Build/Compile/$(PKG_NAME))
|
||||
$(MAKE) -C $(PKG_BUILD_DIR)/ \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
CFLAGS="$(TARGET_CFLAGS)" \
|
||||
CPPFLAGS="$(TARGET_CPPFLAGS)" \
|
||||
LDFLAGS="$(TARGET_LDFLAGS) -ldl"
|
||||
endef
|
||||
|
||||
define Package/mentohust/install
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/mentohust $(1)/usr/sbin/
|
||||
$(INSTALL_DIR) $(1)/etc
|
||||
$(INSTALL_CONF) $(PKG_BUILD_DIR)/mentohust.conf $(1)/etc/mentohust.conf
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,$(PKG_NAME)))
|
276
MentoHUST-OpenWrt-ipk/README.md
Normal file
276
MentoHUST-OpenWrt-ipk/README.md
Normal file
@ -0,0 +1,276 @@
|
||||
# MentoHUST-OpenWrt-ipk
|
||||
|
||||
这是一个积累了很长时间的项目。从2014年起,就陆续在折腾这些东西,期间还自己写了一个基于OpenWrt的神州数码客户端[802.1X Evasi0n](https://github.com/KyleRicardo/802.1X-Evasi0n),服役了大半年的时间,表现良好,内存占用小,工作效率高。后来,学校所有神州数码服务器全部换成了锐捷,导致我的项目失去了光彩,我又翻出了大名鼎鼎的MentoHUST,在反复折腾交叉编译和功能性修补过程中,有了这样一个版本。该版本非常适合于在OpenWrt的SDK环境下编译出MentoHUST的ipk包。
|
||||
|
||||
|
||||
## 特点
|
||||
|
||||
- 修复了原MentoHUST在shell下由于libiconv库编译或工作不正常导致的反馈信息乱码问题
|
||||
- 去除了libiconv库的依赖,加入了轻量级的strnormalize库,GBK to UTF-8转换良好
|
||||
- 去除configure等冗余文件,仅保留核心src源码文件
|
||||
- ./src/Makefile中使用通配符`*`指代libpcap版本,通用性更强
|
||||
- 无需手动配置环境变量,无需使用automake和configure生成所需Makefile
|
||||
- 重新完全手动编写./和./src/目录下的Makefile,保证编译的有效性
|
||||
- 无`--disable-notify --disable-encodepass`等配置,保证原汁原味
|
||||
- 无手动`#define NO_DYLOAD`补丁,使用动态加载库函数,ipk包更小,并且更容易编译
|
||||
|
||||
|
||||
## PreOperation
|
||||
|
||||
### 预备知识
|
||||
|
||||
> 这里的编译是指交叉编译。所谓交叉编译,简单地说,就是在一个平台上生成另一个平台上的可执行代码。这里需要注意的是所谓 平台,实际上包含两个概念:体系结构(Architecture)、操作系统(Operating System)。同一个体系结构可以运行不同的操作系统;同样,同一个操作系统也可以在不同的体系结构上运行。
|
||||
> 交叉编译通常是不得已而为之,有时是因为目的平台上不允许或不能够安装我们所需要的编译器,而我们又需要这个编译器的某些特征;有时是因为目的平台上的资源贫乏,无法运行我们所需要编译器;有时又是因为目的平台还没有建立,连操作系统都没有,根本谈不上运行什么编译器。
|
||||
|
||||
> OpenWrt系统是基于Linux平台的操作系统,故我们需要用到Linux的操作系统平台进行交叉编译。但由于种种原因,我们的电脑不可能使用Linux操作系统,但又要交叉编译,怎么办呢?这时候就需要用到虚拟机了。
|
||||
|
||||
### 需要的工具
|
||||
- VMWare Workstation虚拟机工具
|
||||
- 一个Ubuntu Linux镜像(版本无所谓,笔者用的是15.04版本 x86)
|
||||
- OpenWrt SDK(**不建议**自行从网上下载,建议直接在Ubuntu中用git clone)
|
||||
- 本项目的源码
|
||||
|
||||
### 虚拟机的安装(Tips)
|
||||
关于虚拟机,在这里不多赘述,仅提供一些Tips。如果对虚拟机完全不了解,建议不要继续观看本教程,先找百度谷歌充充电。
|
||||
|
||||
- 推荐新手使用**Ubuntu**
|
||||
|
||||
> 虚拟机的Linux系统推荐使用Ubuntu,对于我们新手来说,这无疑是最适合于我们的系统,图形化的界面很贴心,基本操作上和Windows相差不大,可以较快的熟悉起来。
|
||||
|
||||
- 务必安装VMWare Tools工具
|
||||
|
||||
> 使用VMWare Workstation装Ubuntu的时候,千万不要选择简易安装,这样在后面安装VMware Tools会非常麻烦。先建立一个空虚拟机,然后再用镜像引导安装,这样就比较好,系统安装好了之后再安装上VMWare Tools你会发现这个Tools有多么方便。其中最大的好处有二:系统分辨率的自动调整和剪贴板的无缝连接。就是说,不管文字或者文件,你在windows里面使用Ctrl+C复制后,可以直接在Ubuntu里面粘贴,反之亦然。这在后面将给我们提供非常大的方便。所以,VMWare Tools必须安装,切记。
|
||||
|
||||
- 务必关闭Ubuntu系统屏保
|
||||
|
||||
> 还有一点需要提醒的是,安装好后,在右上角“系统”菜单的“首选项”中选择“屏幕保护程序”,然后去掉左下角的“计算机空闲时激活屏幕保护程序”,然后按“关闭”,这个窗口是没有“应用”或“确定”之类的,直接关闭它就会保存。用惯了WINDOWS的用户注意了。为什么要做这步呢?因为整个编译过程中有些步骤要等一段时间的,老是自动启用屏幕保护程序,然后还要重新输密码才能退出,也是麻烦事。开始的时候我忘了设置这一步,后来有一次把黑屏状态的虚拟机唤醒的时候,显卡瞬间崩溃了,虚拟机直接死机,然后编译了好久的数据丢失了,白白浪费了几个小时。这个教训也希望大家引起重视。
|
||||
|
||||
## PreCompile
|
||||
现在进入正题了,首先要做的是配置好SDK的交叉编译环境。
|
||||
|
||||
### 获取OpenWrt SDK
|
||||
|
||||
首先安装 subversion 和 git,两个应用广泛的源代码管理方案,在此需要这两个工具下载源代码,也就是`svn`和`git`命令。其方法如下:
|
||||
使用`Ctrl+Alt+T`组合快捷键打开终端,然后在左侧的Dock中,右键单击,将其锁定,方便以后打开。如下图:
|
||||
|
||||
![terminal](https://ws1.sinaimg.cn/large/8832d37agy1fxkp9lt8qbj215p0q8adn.jpg)打开终端后,在其中输入如下命令:
|
||||
```
|
||||
$ sudo apt-get update
|
||||
$ sudo apt-get install git
|
||||
```
|
||||
其中,`sudo`是linux系统管理指令,是允许系统管理员让普通用户执行一些或者全部的root命令的一个工具,如`halt`,`reboot`,`su`等等。这样不仅减少了root用户的登录和管理时间,同样也提高了安全性。sudo不是对shell的一个代替,它是面向每个命令的。
|
||||
|
||||
`apt-get`是一条linux命令,适用于deb包管理式的操作系统,主要用于自动从互联网的软件仓库中搜索、安装、升级、卸载软件或操作系统。其简写为`apt`。
|
||||
|
||||
这两条命令执行后,我们就可以用`git`命令获取所需要的源代码了。
|
||||
|
||||
但是,编译源代码还有一些必须的工具和依赖,在这里我们一并安上,这种东西不怕安多了,就怕安少了。执行如下命令:
|
||||
|
||||
```bash
|
||||
$ sudo apt install curl build-essential libncurses5-dev zlib1g-dev gawk flex quilt libssl-dev xsltproc libxml-parser-perl mercurial bzr ecj cvs unzip
|
||||
```
|
||||
|
||||
下面就是来获取trunk版本的SDK了,执行命令:
|
||||
|
||||
```bash
|
||||
$ git clone https://git.openwrt.org/openwrt/openwrt.git
|
||||
```
|
||||
|
||||
cd到我们的SDK目录下,这就是OpenWrt开发环境的根目录。后面几乎所有的操作都是在这个目录下进行:
|
||||
```bash
|
||||
$ cd openwrt/
|
||||
```
|
||||
可以利用Ubuntu的自动填充,就是输入`cd op`然后按一下Tab键,就会自动填充为上面的命令。记住这一点,以后会经常用到,熟练使用自动填充会节约不少时间。
|
||||
|
||||
### 更新feeds
|
||||
Feeds,也就是软件包列表,是在OpenWrt中共用位置的包的集合。运行以下命令即可更新内置软件包列表并链接到编译工具中:
|
||||
```
|
||||
$ ./scripts/feeds update
|
||||
$ ./scripts/feeds install
|
||||
```
|
||||
如果网速不快,可能需要等待一段时间。静待其完成后,我们的feeds就被更新了。
|
||||
从github上下载我已经开源的evasi0n软件包。
|
||||
将我们的evasi0n文件夹直接放入trunk/package/目录下即可。
|
||||
|
||||
### 添加需要编译的第三方软件包(也就是我们的MentoHUST-OpenWrt-ipk),指定目标架构
|
||||
|
||||
首先要在GitHub上clone此repo至package/mentohust目录下。执行命令:
|
||||
|
||||
```bash
|
||||
$ git clone https://github.com/KyleRicardo/MentoHUST-OpenWrt-ipk.git package/mentohust
|
||||
```
|
||||
|
||||
这里说一下我的Makefile。
|
||||
一个工程中的源文件不计其数,其按类型、功能、模块分别放在若干个目录中,Makefile定义了一系列的规则来指定,哪些文件需要先编译,哪些文件需要后编译,哪些文件需要重新编译,甚至于进行更复杂的功能操作,因为 Makefile就像一个Shell脚本一样,其中也可以执行操作系统的命令。
|
||||
|
||||
Makefile的语法规则并不算复杂,但是新手研究起来也很头大,也不能静下心来去花时间学习Makefile的写法。我虽然起初不会写Makefile,但是折腾了这么久之后,对于一个Makefile,已经不算什么了。于是github上包含了我写的Makefile,同学们可以直接编译。下个版本可能会发布自动从网上下载源码并编译的Makefile。
|
||||
|
||||
原始的mentohust编码转换是使用的libiconv库,这个库问题特别多,效率低,不方便编译,受802.1X Evasi0n项目的启发,我干脆摒弃了libiconv库,使用了strnormalize这个文件代替了它,一次性解决了编码转换问题。所以现在,Makefile里面再也找不到iconv的依赖了,现在mentohust唯一依赖的库就是libpcap,编译起来也是相当轻松了。
|
||||
|
||||
Makefile既然已经包括在源码中,那么我们可以开始配置我们的编译器了。使用命令:
|
||||
```
|
||||
$ make menuconfig
|
||||
```
|
||||
这个命令会启用图形化的选项,我们在其中进行调节即可。
|
||||
|
||||
我们一共要调整三个选项:
|
||||
> Target System
|
||||
> Subtarget
|
||||
> Target Profile
|
||||
|
||||
对于极壹,调整好后应该如下图所示:
|
||||
|
||||
![HiWiFi](https://ws1.sinaimg.cn/large/8832d37agy1fxkpauo1zyj215p0q8wk7.jpg)
|
||||
|
||||
对于小米Mini,调整好应该如下图所示:
|
||||
|
||||
![XiaoMi Mini](https://wx4.sinaimg.cn/large/8832d37agy1fxkpbdkdezj215p0q8teh.jpg)
|
||||
|
||||
下面一步,就是把我们要编译的软件包含进去。
|
||||
|
||||
在Makefile里面我们已经知道,这个软件包是属于Network里的Ruijie,所以我们在主菜单中找到Network,回车进入,然后找到Ruijie这一项
|
||||
|
||||
![Ruijie](https://ws3.sinaimg.cn/large/8832d37agy1fxkpcgym9xj215p0q8afx.jpg)
|
||||
|
||||
然后到这里
|
||||
|
||||
![mentohust](https://ws2.sinaimg.cn/large/8832d37agy1fxkpcox4yvj215p0q8tcv.jpg)
|
||||
|
||||
这里不要按Y选中,Y选中是将其编译到固件中去,我们在这里不是要编译固件,而是要神州数码单独作为一个软件编译出来。所以我们按M键选中,将其编译为一个组件模块(Module)。
|
||||
|
||||
用M键选中后,我们用光标键右几次选中Save,保存后,再多次Exit,最终退出这个界面。
|
||||
|
||||
|
||||
|
||||
### 更新编译必需工具与工具链(编译依赖)
|
||||
|
||||
|
||||
|
||||
这一步是从官网上获取我们编译所需的工具(如编译器、链接器等),十分关键。不过,命令却十分简单:
|
||||
|
||||
```
|
||||
$ make tools/install
|
||||
```
|
||||
|
||||
即可编译并安装好我们所需的工具。
|
||||
|
||||
```
|
||||
$ make toolchain/install
|
||||
```
|
||||
|
||||
即可编译并安装好我们所需的工具链。
|
||||
|
||||
为了显示编译过程,我们可以在命令后面加上一个选项:V=s。即:
|
||||
```
|
||||
$ make tools/install V=s
|
||||
$ make toolchain/install V=s
|
||||
```
|
||||
注意,V一定要大写。
|
||||
|
||||
不幸的是,我发现Tools和Toolchain的编译十分漫长,等待过程十分痛苦。这是因为需要从网上下载大量的文件,而这些镜像源都不是特别好。为了减少等待的时间,不妨给大家分享一个小技巧。通过研究编译的过程我发现,所需的文件是下载并保存到openwrt目录的dl文件夹下的。通过实验,我发现这个dl文件夹可以移植,只要我们的OpenWrt SDK的版本是差不多的,我们可以直接将已经弄好的dl文件夹放在openwrt目录中,这样可以节省大量时间。编译所需的dl文件夹我均已打包上传,请自行下载。
|
||||
|
||||
[------------百度网盘------------](https://pan.baidu.com/s/1acyd1aAr-QLtWQmy58eZ-g)
|
||||
|
||||
下载后,提取压缩包到openwrt 目录,然后可以删掉该压缩包。
|
||||
|
||||
同样地,不建议直接将形如http://downloads.openwrt.org/snapshots/trunk/ramips/OpenWrt-Toolchain-ramips-for-mipsel_24kec%2bdsp-gcc-4.8-linaro_uClibc-0.9.33.2.tar.bz2的这种文件解压后直接应用于我们的toolchain,因为省略了编译安装过程,后面可能会发生意想不到的错误。dl文件夹我已经提供给大家,Toolchain的编译已经不需要太长时间。不要因小失大。
|
||||
|
||||
## Compile
|
||||
|
||||
```bash
|
||||
$ make package/mentohust/compile V=s
|
||||
```
|
||||
|
||||
如果顺利,编译完成之后就能在`openwrt/bin/packages/YourArchitecture/base`中找到你的ipk包了。还包含其依赖的libpcap.ipk。如果你的路由器默认没有安装libpcap包,可以一并安装。
|
||||
|
||||
![compiled-ipk](https://wx1.sinaimg.cn/large/8832d37agy1fxksnqln5bj215p0q8n5j.jpg)
|
||||
|
||||
## Install
|
||||
|
||||
将上面拷贝出来的mentohust及libpcap的ipk,用上面的方法,利用WinSCP上传到路由器的tmp目录。这个操作很简单,这里不再赘述。
|
||||
|
||||
使用快捷键`Ctrl+P`打开PuTTY,输入密码(默认是admin)回车后,来到如下界面:
|
||||
|
||||
![pandorabox](https://ws3.sinaimg.cn/large/8832d37agy1fxkpeg7eg2j20ir0btjrj.jpg)
|
||||
|
||||
然后我们先`cd /tmp/`
|
||||
然后用`opkg`命令安装我们所需的软件包:
|
||||
|
||||
```
|
||||
opkg install libpcap_1.7.4-1_ramips_24kec.ipk
|
||||
opkg install mentohust_0.3.1-1_ramips_24kec.ipk
|
||||
```
|
||||
|
||||
这时有可能会出现这种情况:
|
||||
|
||||
![arch-mismatch](https://ws4.sinaimg.cn/large/8832d37agy1fxkpfctgj9j20ir0btmxg.jpg)
|
||||
|
||||
遇到这种错误,需要修改/etc/opkg.conf文件,对于小米Mini,需要在其尾部追加:
|
||||
|
||||
```
|
||||
arch all 1
|
||||
arch ralink 200
|
||||
arch ramips_24kec 100
|
||||
```
|
||||
|
||||
这样就能正确地安装了:
|
||||
|
||||
![libpcap](https://wx3.sinaimg.cn/large/8832d37agy1fxkpfyu41kj20ua0jgdgv.jpg)
|
||||
|
||||
当然,mentohust也可以了:
|
||||
|
||||
![mentohust](https://ws4.sinaimg.cn/large/8832d37agy1fxkpg99g6zj20ir0btmxg.jpg)
|
||||
|
||||
在有些比较老的路由器固件中安装,会有类似这样的错误:
|
||||
|
||||
> //usr/lib/opkg/info/mentohust: line 4: default_postinst: not found
|
||||
> Collected errors:
|
||||
>
|
||||
> pkg_run_script: package "mentohust" postinst script returned status 127.
|
||||
> opkg_configure: dnsmasq-full.postinst returned 127.
|
||||
|
||||
上述错误原因如下:
|
||||
|
||||
因为evasi0n是基于 trunk 代码编译,所以目前编译出的ipk 包默认带有
|
||||
Package/postinst 脚本
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
[ "${IPKG_NO_SCRIPT}" = "1" ] && exit 0
|
||||
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
|
||||
default_postinst$0 $@
|
||||
```
|
||||
Package/prerm 脚本
|
||||
```
|
||||
#!/bin/sh
|
||||
|
||||
. ${IPKG_INSTROOT}/lib/functions.sh
|
||||
|
||||
default_prerm $0$@
|
||||
```
|
||||
而若不是最新编译的固件, /lib/functions.sh 中是没有 default_postinst default_prerm函数的,所以会造成 127错误。
|
||||
|
||||
临时解决办法:
|
||||
在PuTTY中,键入如下命令并回车:
|
||||
|
||||
`echo -e "\ndefault_postinst() {\n\treturn0\n}\ndefault_prerm() {\n\treturn 0\n}" >> /lib/functions.sh`
|
||||
|
||||
注意,这是一条命令,是用echo命令将这段空函数追加到functions.sh文件尾部。
|
||||
上述错误解决之后,终于可以愉快地安装mentohust了。
|
||||
|
||||
## Usage
|
||||
|
||||
安装好后可以立即使用,配置文件在`/etc/mentohust.conf`,可以自行编辑。
|
||||
|
||||
关于mentohust的用法,想必不用我多说吧。我都已经帮忙帮到这一步了。这里提一下,mentohust未能智能识别路由器WAN口对应的网卡,请手动在mentohust.conf的末尾DHCP脚本中添加自己WAN口对应的网卡。最终脚本类似`udhcpc -i eth1`。
|
||||
|
||||
最后,可以将mentohust添加到开机启动,怎么弄不用我多说了吧。
|
||||
|
||||
## 已知问题
|
||||
|
||||
- mentohust未能智能识别路由器WAN口对应的网卡,请手动在mentohust.conf的末尾DHCP脚本中添加自己WAN口对应的网卡。最终脚本类似`udhcpc -i eth1`
|
||||
- 暂未加入init.d目录的mentohust脚本,可能下个版本加入。
|
||||
- 后续可能加入只有一个Makefile,通过自动从git下载源码进行编译的版本
|
||||
|
46
MentoHUST-OpenWrt-ipk/src/Makefile
Normal file
46
MentoHUST-OpenWrt-ipk/src/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
CC = mips-openwrt-linux-gcc
|
||||
CFLAGS = -Wall -g -O2
|
||||
INC_DIR= $(STAGING_DIR)/usr/include -I$(BUILD_DIR)/libpcap-*/ipkg-install/usr/include
|
||||
LINK_DIR= $(STAGING_DIR)/usr/lib -L$(BUILD_DIR)/libpcap-*/ipkg-install/usr/lib
|
||||
LIBS= $(BUILD_DIR)/libpcap-*/ipkg-install/usr/lib/libpcap.a
|
||||
|
||||
OBJ = mentohust.o dlfunc.o md5.o mycheck.o myconfig.o myfunc.o strnormalize.o myini.o mystate.o
|
||||
.PHONY: all
|
||||
|
||||
all: mentohust
|
||||
|
||||
mentohust: $(OBJ)
|
||||
$(CC) $(CFLAGS) -o $@ $(OBJ) $(LIBS) -I$(INC_DIR) -L$(LINK_DIR) $(LDFLAGS)
|
||||
|
||||
mentohust.o : mentohust.c
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
dlfunc.o : dlfunc.c
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
md5.o : md5.c md5.h
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
strnormalize.o: strnormalize.c strnormalize.h
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
mycheck.o : mycheck.c
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
myconfig.o : myconfig.c
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
myfunc.o : myfunc.c
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
myini.o : myini.c
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
mystate.o : mystate.c
|
||||
$(CC) $(CFLAGS) -c $< -I$(INC_DIR)
|
||||
|
||||
clean :
|
||||
rm -v $(OBJ) mentohust
|
153
MentoHUST-OpenWrt-ipk/src/dlfunc.c
Normal file
153
MentoHUST-OpenWrt-ipk/src/dlfunc.c
Normal file
@ -0,0 +1,153 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:dlfunc.c
|
||||
* 摘 要:动态载入库函数
|
||||
* 作 者:HustMoon@BYHH
|
||||
* 邮 箱:www.ehust@gmail.com
|
||||
* 日 期:2009.11.11
|
||||
*/
|
||||
#include "dlfunc.h"
|
||||
|
||||
#ifndef NO_DYLOAD
|
||||
#include <dlfcn.h>
|
||||
|
||||
int (*pcap_findalldevs)(pcap_if_t **, char *);
|
||||
void (*pcap_freealldevs)(pcap_if_t *);
|
||||
pcap_t *(*pcap_open_live)(const char *, int, int, int, char *);
|
||||
int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
|
||||
int (*pcap_setfilter)(pcap_t *, struct bpf_program *);
|
||||
char *(*pcap_geterr)(pcap_t *);
|
||||
void (*pcap_freecode)(struct bpf_program *);
|
||||
int (*pcap_loop)(pcap_t *, int, pcap_handler, unsigned char *);
|
||||
void (*pcap_close)(pcap_t *);
|
||||
void (*pcap_breakloop)(pcap_t *);
|
||||
int (*pcap_sendpacket)(pcap_t *, const unsigned char *, int);
|
||||
|
||||
static void *libpcap = NULL;
|
||||
|
||||
int load_libpcap(void) {
|
||||
char *error;
|
||||
#ifdef MAC_OS
|
||||
char *file[] = {"libpcap.dylib", "libpcap.A.dylib"};
|
||||
int i, count = 2;
|
||||
#else
|
||||
char *file[] = {"libpcap.so", "libpcap.so.1", "libpcap.so.1.0", "libpcap.so.0.9", "libpcap.so.0.8"};
|
||||
int i, count = 5;
|
||||
#endif
|
||||
for (i=0; i<count && !libpcap; i++) {
|
||||
libpcap = dlopen(file[i], RTLD_LAZY);
|
||||
error = dlerror();
|
||||
}
|
||||
if (libpcap == NULL) {
|
||||
printf("!! 打开libpcap失败,请检查是否已安装该库文件。\n");
|
||||
return -1;
|
||||
}
|
||||
if ((pcap_findalldevs = dlsym(libpcap, "pcap_findalldevs"), error = dlerror()) != NULL
|
||||
|| (pcap_freealldevs = dlsym(libpcap, "pcap_freealldevs"), error = dlerror()) != NULL
|
||||
|| (pcap_open_live = dlsym(libpcap, "pcap_open_live"), error = dlerror()) != NULL
|
||||
|| (pcap_compile = dlsym(libpcap, "pcap_compile"), error = dlerror()) != NULL
|
||||
|| (pcap_setfilter = dlsym(libpcap, "pcap_setfilter"), error = dlerror()) != NULL
|
||||
|| (pcap_geterr = dlsym(libpcap, "pcap_geterr"), error = dlerror()) != NULL
|
||||
|| (pcap_freecode = dlsym(libpcap, "pcap_freecode"), error = dlerror()) != NULL
|
||||
|| (pcap_loop = dlsym(libpcap, "pcap_loop"), error = dlerror()) != NULL
|
||||
|| (pcap_close = dlsym(libpcap, "pcap_close"), error = dlerror()) != NULL
|
||||
|| (pcap_breakloop = dlsym(libpcap, "pcap_breakloop"), error = dlerror()) != NULL
|
||||
|| (pcap_sendpacket = dlsym(libpcap, "pcap_sendpacket"), error = dlerror()) != NULL) {
|
||||
printf("!! 从libpcap获取函数失败: %s\n", error);
|
||||
free_libpcap();
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_libpcap(void) {
|
||||
if (libpcap) {
|
||||
dlclose(libpcap);
|
||||
dlerror();
|
||||
libpcap = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* NO_DYLOAD */
|
||||
|
||||
#ifndef NO_NOTIFY
|
||||
#include <dlfcn.h>
|
||||
|
||||
typedef void NotifyNotification, GtkWidget, GError;
|
||||
typedef char gchar;
|
||||
typedef int gint, gboolean;
|
||||
|
||||
static gboolean (*notify_notification_update)(NotifyNotification *, const gchar *,
|
||||
const gchar *, const gchar *);
|
||||
static void (*notify_notification_set_timeout)(NotifyNotification *, gint);
|
||||
static gboolean (*notify_notification_show)(NotifyNotification *, GError **);
|
||||
|
||||
static void *libnotify = NULL;
|
||||
static NotifyNotification *notify = NULL;
|
||||
|
||||
int load_libnotify(void) {
|
||||
char *error;
|
||||
gboolean (*notify_init)(const char *);
|
||||
NotifyNotification *(*notify_notification_new)(const gchar *, const gchar *,
|
||||
const gchar *, GtkWidget *);
|
||||
#ifdef MAC_OS
|
||||
char *file[] = {"libnotify.dylib", "libnotify.1.dylib"};
|
||||
int i, count = 2;
|
||||
#else
|
||||
char *file[] = {"libnotify.so", "libnotify.so.1"};
|
||||
int i, count = 2;
|
||||
#endif
|
||||
for (i=0; i<count && !libnotify; i++) {
|
||||
libnotify = dlopen(file[i], RTLD_LAZY);
|
||||
error = dlerror();
|
||||
}
|
||||
if (libnotify == NULL) {
|
||||
printf("!! 打开libnotify失败,请检查是否已安装该库文件。\n");
|
||||
return -1;
|
||||
}
|
||||
if ((notify_init = dlsym(libnotify, "notify_init"), error = dlerror()) != NULL
|
||||
|| (notify_notification_new = dlsym(libnotify, "notify_notification_new"), error = dlerror()) != NULL
|
||||
|| (notify_notification_show = dlsym(libnotify, "notify_notification_show"), error = dlerror()) != NULL
|
||||
|| (notify_notification_update = dlsym(libnotify, "notify_notification_update"), error = dlerror()) != NULL
|
||||
|| (notify_notification_set_timeout = dlsym(libnotify, "notify_notification_set_timeout"), error = dlerror()) != NULL) {
|
||||
printf("!! 从libnotify获取函数失败: %s\n", error);
|
||||
free_libnotify();
|
||||
return -1;
|
||||
}
|
||||
if (!notify_init("mentohust")) {
|
||||
printf("!! 初始化libnotify失败。\n");
|
||||
free_libnotify();
|
||||
return -1;
|
||||
}
|
||||
notify = notify_notification_new("MentoHUST", NULL, NULL, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void free_libnotify(void) {
|
||||
void (*notify_uninit)(void);
|
||||
if (notify) {
|
||||
notify_uninit = dlsym(libnotify, "notify_uninit");
|
||||
if (!dlerror())
|
||||
notify_uninit();
|
||||
notify = NULL;
|
||||
}
|
||||
if (libnotify) {
|
||||
dlclose(libnotify);
|
||||
dlerror();
|
||||
libnotify = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void set_timeout(int timeout) {
|
||||
notify_notification_set_timeout(notify, timeout);
|
||||
}
|
||||
|
||||
void show_notify(const char *summary, char *body) {
|
||||
notify_notification_update(notify, summary, body, NULL);
|
||||
notify_notification_show(notify, NULL);
|
||||
}
|
||||
|
||||
#endif /* NO_NOTIFY */
|
||||
|
77
MentoHUST-OpenWrt-ipk/src/dlfunc.h
Normal file
77
MentoHUST-OpenWrt-ipk/src/dlfunc.h
Normal file
@ -0,0 +1,77 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* 文件名称:dlfunc.h
|
||||
* 摘 要:动态载入库函数
|
||||
*/
|
||||
#ifndef HUSTMOON_DLFUNC_H
|
||||
#define HUSTMOON_DLFUNC_H
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#endif
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#define PCAP_ERRBUF_SIZE 256
|
||||
#define PCAP_IF_LOOPBACK 0x00000001
|
||||
|
||||
typedef unsigned int bpf_u_int32;
|
||||
typedef void pcap_t;
|
||||
typedef struct pcap_if {
|
||||
struct pcap_if *next;
|
||||
char *name;
|
||||
char *description;
|
||||
void *addresses;
|
||||
bpf_u_int32 flags;
|
||||
}pcap_if_t;
|
||||
struct bpf_program {
|
||||
unsigned int bf_len;
|
||||
void *bf_insns;
|
||||
};
|
||||
struct pcap_pkthdr {
|
||||
struct timeval ts;
|
||||
bpf_u_int32 caplen;
|
||||
bpf_u_int32 len;
|
||||
};
|
||||
typedef void (*pcap_handler)(unsigned char *, const struct pcap_pkthdr *, const unsigned char *);
|
||||
|
||||
#ifdef NO_DYLOAD
|
||||
int pcap_findalldevs(pcap_if_t **, char *);
|
||||
void pcap_freealldevs(pcap_if_t *);
|
||||
pcap_t *pcap_open_live(const char *, int, int, int, char *);
|
||||
int pcap_compile(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
|
||||
int pcap_setfilter(pcap_t *, struct bpf_program *);
|
||||
char *pcap_geterr(pcap_t *);
|
||||
void pcap_freecode(struct bpf_program *);
|
||||
int pcap_loop(pcap_t *, int, pcap_handler, unsigned char *);
|
||||
void pcap_close(pcap_t *);
|
||||
void pcap_breakloop(pcap_t *);
|
||||
int pcap_sendpacket(pcap_t *, const unsigned char *, int);
|
||||
|
||||
#else
|
||||
extern int (*pcap_findalldevs)(pcap_if_t **, char *);
|
||||
extern void (*pcap_freealldevs)(pcap_if_t *);
|
||||
extern pcap_t *(*pcap_open_live)(const char *, int, int, int, char *);
|
||||
extern int (*pcap_compile)(pcap_t *, struct bpf_program *, const char *, int, bpf_u_int32);
|
||||
extern int (*pcap_setfilter)(pcap_t *, struct bpf_program *);
|
||||
extern char *(*pcap_geterr)(pcap_t *);
|
||||
extern void (*pcap_freecode)(struct bpf_program *);
|
||||
extern int (*pcap_loop)(pcap_t *, int, pcap_handler, unsigned char *);
|
||||
extern void (*pcap_close)(pcap_t *);
|
||||
extern void (*pcap_breakloop)(pcap_t *);
|
||||
extern int (*pcap_sendpacket)(pcap_t *, const unsigned char *, int);
|
||||
|
||||
int load_libpcap(void); /* 载入libpcap.so */
|
||||
void free_libpcap(void); /* 释放libpcap.so */
|
||||
|
||||
#endif /* NO_DYLOAD */
|
||||
|
||||
#ifndef NO_NOTIFY
|
||||
int load_libnotify(void); /* 载入libnotify.so */
|
||||
void free_libnotify(void); /* 释放libnotify.so */
|
||||
void set_timeout(int timeout); /* 设置超时间隔 */
|
||||
void show_notify(const char *summary, char *body); /* 显示通知:概要、正文 */
|
||||
#endif /* NO_NOTIFY */
|
||||
|
||||
#endif /* HUSTMOON_DLFUNC_H */
|
||||
|
297
MentoHUST-OpenWrt-ipk/src/md5.c
Normal file
297
MentoHUST-OpenWrt-ipk/src/md5.c
Normal file
@ -0,0 +1,297 @@
|
||||
/* MD5.c - an implementation of md5 algorithm */
|
||||
|
||||
/* Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.
|
||||
*/
|
||||
#include "md5.h"
|
||||
#include <string.h>
|
||||
|
||||
/* Constants for MD5Transform routine. */
|
||||
#define S11 7
|
||||
#define S12 12
|
||||
#define S13 17
|
||||
#define S14 22
|
||||
#define S21 5
|
||||
#define S22 9
|
||||
#define S23 14
|
||||
#define S24 20
|
||||
#define S31 4
|
||||
#define S32 11
|
||||
#define S33 16
|
||||
#define S34 23
|
||||
#define S41 6
|
||||
#define S42 10
|
||||
#define S43 15
|
||||
#define S44 21
|
||||
|
||||
static void MD5Transform(UINT4 [4], UCHAR [64]);
|
||||
static void Encode(UCHAR *, UINT4 *, UINT4);
|
||||
static void Decode(UINT4 *, UCHAR *, UINT4);
|
||||
|
||||
static UCHAR PADDING[64] = {
|
||||
0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
|
||||
};
|
||||
|
||||
/* F, G, H and I are basic MD5 functions.
|
||||
*/
|
||||
#define F(x, y, z) (((x) & (y)) | ((~x) & (z)))
|
||||
#define G(x, y, z) (((x) & (z)) | ((y) & (~z)))
|
||||
#define H(x, y, z) ((x) ^ (y) ^ (z))
|
||||
#define I(x, y, z) ((y) ^ ((x) | (~z)))
|
||||
|
||||
/* ROTATE_LEFT rotates x left n bits.
|
||||
*/
|
||||
#define ROTATE_LEFT(x, n) (((x) << (n)) | ((x) >> (32-(n))))
|
||||
|
||||
/* FF, GG, HH, and II transformations for rounds 1, 2, 3, and 4.
|
||||
Rotation is separate from addition to prevent recomputation.
|
||||
*/
|
||||
#define FF(a, b, c, d, x, s, ac) { \
|
||||
(a) += F ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define GG(a, b, c, d, x, s, ac) { \
|
||||
(a) += G ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define HH(a, b, c, d, x, s, ac) { \
|
||||
(a) += H ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
#define II(a, b, c, d, x, s, ac) { \
|
||||
(a) += I ((b), (c), (d)) + (x) + (UINT4)(ac); \
|
||||
(a) = ROTATE_LEFT ((a), (s)); \
|
||||
(a) += (b); \
|
||||
}
|
||||
|
||||
/* MD5 initialization. Begins an MD5 operation, writing a new context.
|
||||
*/
|
||||
void MD5Init (MD5_CTX * context)
|
||||
|
||||
{
|
||||
context->count[0] = context->count[1] = 0;
|
||||
/* Load magic initialization constants.
|
||||
*/
|
||||
context->state[0] = 0x67452301;
|
||||
context->state[1] = 0xefcdab89;
|
||||
context->state[2] = 0x98badcfe;
|
||||
context->state[3] = 0x10325476;
|
||||
}
|
||||
|
||||
/* MD5 block update operation. Continues an MD5 message-digest
|
||||
operation, processing another message block, and updating the
|
||||
context.
|
||||
*/
|
||||
void MD5Update (MD5_CTX *context, UCHAR *input, UINT4 inputLen)
|
||||
|
||||
{
|
||||
UINT4 i, index, partLen;
|
||||
|
||||
/* Compute number of bytes mod 64 */
|
||||
index = (UINT4)((context->count[0] >> 3) & 0x3F);
|
||||
|
||||
/* Update number of bits */
|
||||
if ((context->count[0] += ((UINT4)inputLen << 3))
|
||||
< ((UINT4)inputLen << 3))
|
||||
context->count[1]++;
|
||||
context->count[1] += ((UINT4)inputLen >> 29);
|
||||
|
||||
partLen = 64 - index;
|
||||
|
||||
/* Transform as many times as possible.
|
||||
*/
|
||||
if (inputLen >= partLen) {
|
||||
memcpy((POINTER)&context->buffer[index], (POINTER)input, partLen);
|
||||
MD5Transform (context->state, context->buffer);
|
||||
|
||||
for (i = partLen; i + 63 < inputLen; i += 64)
|
||||
MD5Transform (context->state, &input[i]);
|
||||
|
||||
index = 0;
|
||||
}
|
||||
else
|
||||
i = 0;
|
||||
|
||||
/* Buffer remaining input */
|
||||
memcpy((POINTER)&context->buffer[index], (POINTER)&input[i],inputLen-i);
|
||||
}
|
||||
|
||||
/* MD5 finalization. Ends an MD5 message-digest operation, writing the
|
||||
the message digest and zeroizing the context.
|
||||
*/
|
||||
void MD5Final (UCHAR digest[16], MD5_CTX *context)
|
||||
{
|
||||
UCHAR bits[8];
|
||||
UINT4 index, padLen;
|
||||
|
||||
/* Save number of bits */
|
||||
Encode (bits, context->count, 8);
|
||||
|
||||
/* Pad out to 56 mod 64.
|
||||
*/
|
||||
index = (UINT4)((context->count[0] >> 3) & 0x3f);
|
||||
padLen = (index < 56) ? (56 - index) : (120 - index);
|
||||
MD5Update (context, PADDING, padLen);
|
||||
|
||||
/* Append length (before padding) */
|
||||
MD5Update (context, bits, 8);
|
||||
|
||||
/* Store state in digest */
|
||||
Encode (digest, context->state, 16);
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
*/
|
||||
memset ((POINTER)context, 0, sizeof (*context));
|
||||
}
|
||||
|
||||
/* MD5 basic transformation. Transforms state based on block.
|
||||
*/
|
||||
static void MD5Transform (UINT4 state[4],UCHAR block[64])
|
||||
{
|
||||
UINT4 a = state[0], b = state[1], c = state[2], d = state[3], x[16];
|
||||
|
||||
Decode (x, block, 64);
|
||||
|
||||
/* Round 1 */
|
||||
FF (a, b, c, d, x[ 0], S11, 0xd76aa478); /* 1 */
|
||||
FF (d, a, b, c, x[ 1], S12, 0xe8c7b756); /* 2 */
|
||||
FF (c, d, a, b, x[ 2], S13, 0x242070db); /* 3 */
|
||||
FF (b, c, d, a, x[ 3], S14, 0xc1bdceee); /* 4 */
|
||||
FF (a, b, c, d, x[ 4], S11, 0xf57c0faf); /* 5 */
|
||||
FF (d, a, b, c, x[ 5], S12, 0x4787c62a); /* 6 */
|
||||
FF (c, d, a, b, x[ 6], S13, 0xa8304613); /* 7 */
|
||||
FF (b, c, d, a, x[ 7], S14, 0xfd469501); /* 8 */
|
||||
FF (a, b, c, d, x[ 8], S11, 0x698098d8); /* 9 */
|
||||
FF (d, a, b, c, x[ 9], S12, 0x8b44f7af); /* 10 */
|
||||
FF (c, d, a, b, x[10], S13, 0xffff5bb1); /* 11 */
|
||||
FF (b, c, d, a, x[11], S14, 0x895cd7be); /* 12 */
|
||||
FF (a, b, c, d, x[12], S11, 0x6b901122); /* 13 */
|
||||
FF (d, a, b, c, x[13], S12, 0xfd987193); /* 14 */
|
||||
FF (c, d, a, b, x[14], S13, 0xa679438e); /* 15 */
|
||||
FF (b, c, d, a, x[15], S14, 0x49b40821); /* 16 */
|
||||
|
||||
/* Round 2 */
|
||||
GG (a, b, c, d, x[ 1], S21, 0xf61e2562); /* 17 */
|
||||
GG (d, a, b, c, x[ 6], S22, 0xc040b340); /* 18 */
|
||||
GG (c, d, a, b, x[11], S23, 0x265e5a51); /* 19 */
|
||||
GG (b, c, d, a, x[ 0], S24, 0xe9b6c7aa); /* 20 */
|
||||
GG (a, b, c, d, x[ 5], S21, 0xd62f105d); /* 21 */
|
||||
GG (d, a, b, c, x[10], S22, 0x2441453); /* 22 */
|
||||
GG (c, d, a, b, x[15], S23, 0xd8a1e681); /* 23 */
|
||||
GG (b, c, d, a, x[ 4], S24, 0xe7d3fbc8); /* 24 */
|
||||
GG (a, b, c, d, x[ 9], S21, 0x21e1cde6); /* 25 */
|
||||
GG (d, a, b, c, x[14], S22, 0xc33707d6); /* 26 */
|
||||
GG (c, d, a, b, x[ 3], S23, 0xf4d50d87); /* 27 */
|
||||
GG (b, c, d, a, x[ 8], S24, 0x455a14ed); /* 28 */
|
||||
GG (a, b, c, d, x[13], S21, 0xa9e3e905); /* 29 */
|
||||
GG (d, a, b, c, x[ 2], S22, 0xfcefa3f8); /* 30 */
|
||||
GG (c, d, a, b, x[ 7], S23, 0x676f02d9); /* 31 */
|
||||
GG (b, c, d, a, x[12], S24, 0x8d2a4c8a); /* 32 */
|
||||
|
||||
/* Round 3 */
|
||||
HH (a, b, c, d, x[ 5], S31, 0xfffa3942); /* 33 */
|
||||
HH (d, a, b, c, x[ 8], S32, 0x8771f681); /* 34 */
|
||||
HH (c, d, a, b, x[11], S33, 0x6d9d6122); /* 35 */
|
||||
HH (b, c, d, a, x[14], S34, 0xfde5380c); /* 36 */
|
||||
HH (a, b, c, d, x[ 1], S31, 0xa4beea44); /* 37 */
|
||||
HH (d, a, b, c, x[ 4], S32, 0x4bdecfa9); /* 38 */
|
||||
HH (c, d, a, b, x[ 7], S33, 0xf6bb4b60); /* 39 */
|
||||
HH (b, c, d, a, x[10], S34, 0xbebfbc70); /* 40 */
|
||||
HH (a, b, c, d, x[13], S31, 0x289b7ec6); /* 41 */
|
||||
HH (d, a, b, c, x[ 0], S32, 0xeaa127fa); /* 42 */
|
||||
HH (c, d, a, b, x[ 3], S33, 0xd4ef3085); /* 43 */
|
||||
HH (b, c, d, a, x[ 6], S34, 0x4881d05); /* 44 */
|
||||
HH (a, b, c, d, x[ 9], S31, 0xd9d4d039); /* 45 */
|
||||
HH (d, a, b, c, x[12], S32, 0xe6db99e5); /* 46 */
|
||||
HH (c, d, a, b, x[15], S33, 0x1fa27cf8); /* 47 */
|
||||
HH (b, c, d, a, x[ 2], S34, 0xc4ac5665); /* 48 */
|
||||
|
||||
/* Round 4 */
|
||||
II (a, b, c, d, x[ 0], S41, 0xf4292244); /* 49 */
|
||||
II (d, a, b, c, x[ 7], S42, 0x432aff97); /* 50 */
|
||||
II (c, d, a, b, x[14], S43, 0xab9423a7); /* 51 */
|
||||
II (b, c, d, a, x[ 5], S44, 0xfc93a039); /* 52 */
|
||||
II (a, b, c, d, x[12], S41, 0x655b59c3); /* 53 */
|
||||
II (d, a, b, c, x[ 3], S42, 0x8f0ccc92); /* 54 */
|
||||
II (c, d, a, b, x[10], S43, 0xffeff47d); /* 55 */
|
||||
II (b, c, d, a, x[ 1], S44, 0x85845dd1); /* 56 */
|
||||
II (a, b, c, d, x[ 8], S41, 0x6fa87e4f); /* 57 */
|
||||
II (d, a, b, c, x[15], S42, 0xfe2ce6e0); /* 58 */
|
||||
II (c, d, a, b, x[ 6], S43, 0xa3014314); /* 59 */
|
||||
II (b, c, d, a, x[13], S44, 0x4e0811a1); /* 60 */
|
||||
II (a, b, c, d, x[ 4], S41, 0xf7537e82); /* 61 */
|
||||
II (d, a, b, c, x[11], S42, 0xbd3af235); /* 62 */
|
||||
II (c, d, a, b, x[ 2], S43, 0x2ad7d2bb); /* 63 */
|
||||
II (b, c, d, a, x[ 9], S44, 0xeb86d391); /* 64 */
|
||||
|
||||
state[0] += a;
|
||||
state[1] += b;
|
||||
state[2] += c;
|
||||
state[3] += d;
|
||||
|
||||
/* Zeroize sensitive information.
|
||||
|
||||
*/
|
||||
memset ((POINTER)x, 0, sizeof (x));
|
||||
}
|
||||
|
||||
/* Encodes input (UINT4) into output (UCHAR). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void Encode (UCHAR *output, UINT4 *input, UINT4 len)
|
||||
{
|
||||
UINT4 i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4) {
|
||||
output[j] = (UCHAR)(input[i] & 0xff);
|
||||
output[j+1] = (UCHAR)((input[i] >> 8) & 0xff);
|
||||
output[j+2] = (UCHAR)((input[i] >> 16) & 0xff);
|
||||
output[j+3] = (UCHAR)((input[i] >> 24) & 0xff);
|
||||
}
|
||||
}
|
||||
|
||||
/* Decodes input (UCHAR) into output (UINT4). Assumes len is
|
||||
a multiple of 4.
|
||||
*/
|
||||
static void Decode (UINT4 *output, UCHAR *input, UINT4 len)
|
||||
{
|
||||
UINT4 i, j;
|
||||
|
||||
for (i = 0, j = 0; j < len; i++, j += 4)
|
||||
output[i] = ((UINT4)input[j]) | (((UINT4)input[j+1]) << 8) |
|
||||
(((UINT4)input[j+2]) << 16) | (((UINT4)input[j+3]) << 24);
|
||||
}
|
||||
|
||||
/*Compute the md5sum (return static-local-variable),whose length is 16 bytes.*/
|
||||
UCHAR* ComputeHash(UCHAR* src, UINT4 len)
|
||||
{
|
||||
MD5_CTX context;
|
||||
static UCHAR digest[16];
|
||||
MD5Init(&context);
|
||||
MD5Update(&context, src, len);
|
||||
MD5Final(digest, &context);
|
||||
return digest;
|
||||
}
|
43
MentoHUST-OpenWrt-ipk/src/md5.h
Normal file
43
MentoHUST-OpenWrt-ipk/src/md5.h
Normal file
@ -0,0 +1,43 @@
|
||||
/* MD5.H - header file for MD5.C */
|
||||
|
||||
/*
|
||||
Copyright (C) 1991-2, RSA Data Security, Inc. Created 1991. All
|
||||
rights reserved.
|
||||
|
||||
License to copy and use this software is granted provided that it
|
||||
is identified as the "RSA Data Security, Inc. MD5 Message-Digest
|
||||
Algorithm" in all material mentioning or referencing this software
|
||||
or this function.
|
||||
|
||||
License is also granted to make and use derivative works provided
|
||||
that such works are identified as "derived from the RSA Data
|
||||
Security, Inc. MD5 Message-Digest Algorithm" in all material
|
||||
mentioning or referencing the derived work.
|
||||
|
||||
RSA Data Security, Inc. makes no representations concerning either
|
||||
the merchantability of this software or the suitability of this
|
||||
software for any particular purpose. It is provided "as is"
|
||||
without express or implied warranty of any kind.
|
||||
|
||||
These notices must be retained in any copies of any part of this
|
||||
documentation and/or software.*/
|
||||
|
||||
#ifndef MD5_H
|
||||
#define MD5_H
|
||||
#include "types.h"
|
||||
|
||||
/* MD5 context. */
|
||||
typedef struct
|
||||
{
|
||||
UINT4 state[4]; /* state (ABCD) */
|
||||
UINT4 count[2]; /* number of bits, modulo 2^64 (lsb first) */
|
||||
UCHAR buffer[64]; /* input buffer */
|
||||
} MD5_CTX;
|
||||
|
||||
void MD5Init(MD5_CTX * context);
|
||||
void MD5Update(MD5_CTX *context, UCHAR *input, UINT4 inputLen);
|
||||
void MD5Final(UCHAR digest[16], MD5_CTX *context);
|
||||
|
||||
UCHAR* ComputeHash(UCHAR *src, UINT4 len);
|
||||
|
||||
#endif /* MD5_H */
|
278
MentoHUST-OpenWrt-ipk/src/mentohust.c
Normal file
278
MentoHUST-OpenWrt-ipk/src/mentohust.c
Normal file
@ -0,0 +1,278 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:mentohust.c
|
||||
* 摘 要:MentoHUST主函数
|
||||
* 作 者:HustMoon@BYHH
|
||||
* 邮 箱:www.ehust@gmail.com
|
||||
*/
|
||||
|
||||
#include "strnormalize.h"
|
||||
|
||||
#include "myconfig.h"
|
||||
#include "mystate.h"
|
||||
#include "myfunc.h"
|
||||
#include "dlfunc.h"
|
||||
|
||||
#include <signal.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern pcap_t *hPcap;
|
||||
extern volatile int state;
|
||||
extern u_char *fillBuf;
|
||||
extern const u_char *capBuf;
|
||||
extern unsigned startMode, dhcpMode, maxFail;
|
||||
extern u_char destMAC[];
|
||||
extern int lockfd;
|
||||
#ifndef NO_NOTIFY
|
||||
extern int showNotify;
|
||||
#endif
|
||||
#ifndef NO_ARP
|
||||
extern u_int32_t rip, gateway;
|
||||
extern u_char gateMAC[];
|
||||
#endif
|
||||
|
||||
static void exit_handle(void); /* 退出回调 */
|
||||
static void sig_handle(int sig); /* 信号回调 */
|
||||
static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf); /* pcap_loop回调 */
|
||||
static void showRuijieMsg(const u_char *buf, unsigned bufLen); /* 显示锐捷服务器提示信息 */
|
||||
static void showCernetMsg(const u_char *buf); /* 显示赛尔服务器提示信息 */
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
atexit(exit_handle);
|
||||
initConfig(argc, argv);
|
||||
signal(SIGALRM, sig_handle); /* 定时器 */
|
||||
signal(SIGHUP, sig_handle); /* 注销时 */
|
||||
signal(SIGINT, sig_handle); /* Ctrl+C */
|
||||
signal(SIGQUIT, sig_handle); /* Ctrl+\ */
|
||||
signal(SIGTSTP, sig_handle); /* Ctrl+Z */
|
||||
signal(SIGTERM, sig_handle); /* 被结束时 */
|
||||
if (dhcpMode == 3) /* 认证前DHCP */
|
||||
switchState(ID_DHCP);
|
||||
else
|
||||
switchState(ID_START); /* 开始认证 */
|
||||
if (-1 == pcap_loop(hPcap, -1, pcap_handle, NULL)) { /* 开始捕获数据包 */
|
||||
printf("!! 捕获数据包失败,请检查网络连接!\n");
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 错误提示", "捕获数据包失败,请检查网络连接!");
|
||||
#endif
|
||||
}
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
static void exit_handle(void)
|
||||
{
|
||||
if (state != ID_DISCONNECT)
|
||||
switchState(ID_DISCONNECT);
|
||||
if (hPcap != NULL)
|
||||
pcap_close(hPcap);
|
||||
if (fillBuf != NULL)
|
||||
free(fillBuf);
|
||||
if (lockfd > -1)
|
||||
close(lockfd);
|
||||
#ifndef NO_NOTIFY
|
||||
free_libnotify();
|
||||
#endif
|
||||
#ifndef NO_DYLOAD
|
||||
free_libpcap();
|
||||
#endif
|
||||
printf(">> 认证已退出。\n");
|
||||
}
|
||||
|
||||
static void sig_handle(int sig)
|
||||
{
|
||||
if (sig == SIGALRM) /* 定时器 */
|
||||
{
|
||||
if (-1 == switchState(state))
|
||||
{
|
||||
pcap_breakloop(hPcap);
|
||||
printf("!! 发送数据包失败, 请检查网络连接!\n");
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 错误提示", "发送数据包失败, 请检查网络连接!");
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
else /* 退出 */
|
||||
{
|
||||
pcap_breakloop(hPcap);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
}
|
||||
|
||||
static void pcap_handle(u_char *user, const struct pcap_pkthdr *h, const u_char *buf)
|
||||
{
|
||||
static unsigned failCount = 0;
|
||||
#ifndef NO_ARP
|
||||
if (buf[0x0c]==0x88 && buf[0x0d]==0x8e) {
|
||||
#endif
|
||||
if (memcmp(destMAC, buf+6, 6)!=0 && startMode>2) /* 服务器MAC地址不符 */
|
||||
return;
|
||||
capBuf = buf;
|
||||
if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x01) { /* 验证用户名 */
|
||||
if (startMode < 3) {
|
||||
memcpy(destMAC, buf+6, 6);
|
||||
printf("** 认证MAC:\t%s\n", formatHex(destMAC, 6));
|
||||
startMode += 3; /* 标记为已获取 */
|
||||
}
|
||||
if (startMode==3 && memcmp(buf+0x17, "User name", 9)==0) /* 塞尔 */
|
||||
startMode = 5;
|
||||
switchState(ID_IDENTITY);
|
||||
}
|
||||
else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x04) /* 验证密码 */
|
||||
switchState(ID_CHALLENGE);
|
||||
else if (buf[0x0F]==0x00 && buf[0x12]==0x03) { /* 认证成功 */
|
||||
printf(">> 认证成功!\n");
|
||||
failCount = 0;
|
||||
if (!(startMode%3 == 2)) {
|
||||
getEchoKey(buf);
|
||||
showRuijieMsg(buf, h->caplen);
|
||||
}
|
||||
if (dhcpMode==1 || dhcpMode==2) /* 二次认证第一次或者认证后 */
|
||||
switchState(ID_DHCP);
|
||||
else if (startMode%3 == 2)
|
||||
switchState(ID_WAITECHO);
|
||||
else
|
||||
switchState(ID_ECHO);
|
||||
}
|
||||
else if (buf[0x0F]==0x00 && buf[0x12]==0x01 && buf[0x16]==0x02) /* 显示赛尔提示信息 */
|
||||
showCernetMsg(buf);
|
||||
else if (buf[0x0F] == 0x05) /* (赛尔)响应在线 */
|
||||
switchState(ID_ECHO);
|
||||
else if (buf[0x0F]==0x00 && buf[0x12]==0x04) { /* 认证失败或被踢下线 */
|
||||
if (state==ID_WAITECHO || state==ID_ECHO) {
|
||||
printf(">> 认证掉线,开始重连!\n");
|
||||
switchState(ID_START);
|
||||
}
|
||||
else if (buf[0x1b]!=0 || startMode%3==2) {
|
||||
printf(">> 认证失败!\n");
|
||||
if (startMode%3 != 2)
|
||||
showRuijieMsg(buf, h->caplen);
|
||||
if (maxFail && ++failCount>=maxFail) {
|
||||
printf(">> 连续认证失败%u次,退出认证。\n", maxFail);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
restart();
|
||||
}
|
||||
else
|
||||
switchState(ID_START);
|
||||
}
|
||||
#ifndef NO_ARP
|
||||
} else if (gateMAC[0]!=0xFE && buf[0x0c]==0x08 && buf[0x0d]==0x06) {
|
||||
if (*(u_int32_t *)(buf+0x1c) == gateway) {
|
||||
char str[50];
|
||||
if (gateMAC[0] == 0xFF) {
|
||||
memcpy(gateMAC, buf+0x16, 6);
|
||||
printf("** 网关MAC:\t%s\n", formatHex(gateMAC, 6));
|
||||
fflush(stdout);
|
||||
sprintf(str, "arp -s %s %s", formatIP(gateway), formatHex(gateMAC, 6));
|
||||
system(str);
|
||||
} else if (buf[0x15]==0x02 && *(u_int32_t *)(buf+0x26)==rip
|
||||
&& memcmp(gateMAC, buf+0x16, 6)!=0) {
|
||||
printf("** ARP欺骗:\t%s\n", formatHex(buf+0x16, 6));
|
||||
fflush(stdout);
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify) {
|
||||
sprintf(str, "欺骗源: %s", formatHex(buf+0x16, 6));
|
||||
show_notify("MentoHUST - ARP提示", str);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifndef MAC_OS
|
||||
static char *gbk2utf(char *gbksrc, size_t gbklen) /* GBK转UTF-8 */
|
||||
#else
|
||||
static char *gbk2utf(const char *gbksrc, size_t gbklen) /* GBK转UTF-8 */
|
||||
#endif
|
||||
{
|
||||
|
||||
/* GBK一汉字俩字节,UTF-8一汉字3字节,二者ASCII字符均一字节
|
||||
所以这样申请是足够的了,要记得释放 */
|
||||
str_normalize_init();
|
||||
|
||||
size_t utf8len = gbklen * 3 + 1;
|
||||
char *utf8dst = (char *)malloc(utf8len);
|
||||
|
||||
memset(utf8dst,0,utf8len);
|
||||
|
||||
char *temp=(char *)malloc(gbklen+5);
|
||||
memset(temp, 0, gbklen+5);
|
||||
memcpy(temp,gbksrc,gbklen);
|
||||
gbksrc = temp;
|
||||
gbklen = strlen(gbksrc);
|
||||
|
||||
gbk_to_utf8(gbksrc, gbklen, &utf8dst, &utf8len);
|
||||
|
||||
free(temp);
|
||||
|
||||
return utf8dst;
|
||||
}
|
||||
|
||||
static void showRuijieMsg(const u_char *buf, unsigned bufLen)
|
||||
{
|
||||
char *serverMsg;
|
||||
int length = buf[0x1b];
|
||||
if (length > 0)
|
||||
{
|
||||
for (serverMsg=(char *)(buf+0x1c); *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--); /* 跳过开头的换行符 */
|
||||
if (strlen(serverMsg) < length)
|
||||
length = strlen(serverMsg);
|
||||
if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
|
||||
{
|
||||
printf("$$ 系统提示:\t%s\n", serverMsg);
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 系统提示", serverMsg);
|
||||
#endif
|
||||
free(serverMsg);
|
||||
}
|
||||
}
|
||||
if ((length=0x1c+buf[0x1b]+0x69+39) < bufLen)
|
||||
{
|
||||
serverMsg=(char *)(buf+length);
|
||||
if (buf[length-1]-2 > bufLen-length)
|
||||
length = bufLen - length;
|
||||
else
|
||||
length = buf[length-1]-2;
|
||||
for (; *serverMsg=='\r'||*serverMsg=='\n'; serverMsg++,length--);
|
||||
if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
|
||||
{
|
||||
printf("$$ 计费提示:\t%s\n", serverMsg);
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 计费提示", serverMsg);
|
||||
#endif
|
||||
free(serverMsg);
|
||||
}
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
||||
|
||||
static void showCernetMsg(const u_char *buf)
|
||||
{
|
||||
char *serverMsg = (char *)(buf+0x17);
|
||||
int length = ntohs(*(u_int16_t *)(buf+0x14)) - 5;
|
||||
if (strlen(serverMsg) < length)
|
||||
length = strlen(serverMsg);
|
||||
if (length>0 && (serverMsg=gbk2utf(serverMsg, length))!=NULL)
|
||||
{
|
||||
printf("$$ 系统提示:\t%s\n", serverMsg);
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 系统提示", serverMsg);
|
||||
#endif
|
||||
free(serverMsg);
|
||||
}
|
||||
fflush(stdout);
|
||||
}
|
46
MentoHUST-OpenWrt-ipk/src/mentohust.conf
Normal file
46
MentoHUST-OpenWrt-ipk/src/mentohust.conf
Normal file
@ -0,0 +1,46 @@
|
||||
# MentoHUST for Linux By HustMoon Studio
|
||||
#
|
||||
# 配置文件名称必须是小写/etc/mentohust.conf,编码格式建议是UTF-8
|
||||
# 配置文件中一行开头的空格和Tab会被忽略,其他的会视为参数一部分
|
||||
# 配置文件中Section与Key不区分大小写,以#或;开头的行视为注释
|
||||
# 同一个参数若在命令行参数和配置文件中均有设置,使用命令行参数
|
||||
# 命令行中使用参数-h或-?可查看详细参数信息,建议通过命令行设置参数
|
||||
# 命令行中使用参数-w可将配置更新到/etc/mentohust.conf
|
||||
|
||||
[MentoHUST]
|
||||
;用户名,长度不超过64
|
||||
Username=
|
||||
;密码(简单加密)
|
||||
EncodePass=
|
||||
;网卡
|
||||
Nic=
|
||||
;静态IP用户可以使用非本机IP
|
||||
IP=
|
||||
;掩码,无关紧要
|
||||
Mask=
|
||||
;网关,如果指定了就会监视网关ARP信息
|
||||
Gateway=
|
||||
;DNS服务器,无关紧要
|
||||
DNS=
|
||||
;Ping主机,用于掉线检测,0.0.0.0表示关闭该功能
|
||||
PingHost=
|
||||
;每次发包超时时间(秒)
|
||||
Timeout=
|
||||
;发送Echo包的间隔(秒)
|
||||
EchoInterval=
|
||||
;失败等待(秒)认证失败后等待RestartWait秒或者服务器请求后重启认证
|
||||
RestartWait=
|
||||
;寻找服务器时的组播地址类型 0标准 1锐捷 2将MentoHUST用于赛尔认证
|
||||
StartMode=
|
||||
;DHCP方式 0(不使用) 1(二次认证) 2(认证后) 3(认证前)
|
||||
DhcpMode=
|
||||
;是否后台运行: 0(否) 1(是,关闭输出) 2(是,保留输出) 3(是,输出到文件/tmp/mentohust.log)
|
||||
DaemonMode=
|
||||
;是否显示通知: 0(否) 1~20(是)
|
||||
ShowNotify=
|
||||
;客户端版本号,如果未开启客户端校验但对版本号有要求,可以在此指定,形如3.30
|
||||
Version=
|
||||
;认证数据文件,如果需要校验客户端,就需要正确设置
|
||||
DataFile=
|
||||
;进行DHCP的脚本
|
||||
DhcpScript=
|
189
MentoHUST-OpenWrt-ipk/src/mycheck.c
Normal file
189
MentoHUST-OpenWrt-ipk/src/mycheck.c
Normal file
@ -0,0 +1,189 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:mycheck.c
|
||||
* 摘 要:客户端校验算法
|
||||
* 作 者:kkHAIKE & HustMoon
|
||||
*/
|
||||
#include "mycheck.h"
|
||||
#include "md5.h"
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static BYTE *bin_8021x = NULL;
|
||||
static DWORD size_8021x;
|
||||
static BYTE hex[][17]={"0123456789ABCDEF", "0123456789abcdef"};
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
WORD ltobs(WORD x) {
|
||||
return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);
|
||||
}
|
||||
|
||||
DWORD ltobl(DWORD x) {
|
||||
return ((x & 0xff) << 24) |\
|
||||
((x & 0xff00) << 8) |\
|
||||
((x & 0xff0000) >> 8) |\
|
||||
((x & 0xff000000) >> 24);
|
||||
}
|
||||
#endif
|
||||
|
||||
void hex_to_str(const BYTE *a, char *b, int hexsize, int upper) {
|
||||
BYTE *q = (BYTE *)b;
|
||||
int i;
|
||||
for (i=0; i<hexsize; i++) {
|
||||
*q = hex[upper][a[i]>>4]; q++;
|
||||
*q = hex[upper][a[i]&0xf]; q++;
|
||||
}
|
||||
*q = 0;
|
||||
}
|
||||
|
||||
BYTE *ReadCode(const char *file, DWORD *size) {
|
||||
BYTE *data = NULL;
|
||||
int i;
|
||||
FILE *fp;
|
||||
PPE_HEADER_MAP hpe;
|
||||
|
||||
if ((fp=fopen(file, "rb")) == NULL)
|
||||
goto fileError;
|
||||
data = (BYTE *)malloc(0x1000);
|
||||
if (fread(data, 0x1000, 1, fp) < 1)
|
||||
goto fileError;
|
||||
|
||||
hpe = (PPE_HEADER_MAP)(data + LTOBL(((PIMAGE_DOS_HEADER)data)->e_lfanew));
|
||||
for (i=0; i<LTOBS(hpe->_head.NumberOfSections); i++) {
|
||||
if (LTOBL(hpe->section_header[i].Characteristics) & (IMAGE_SCN_MEM_EXECUTE | IMAGE_SCN_CNT_CODE)) {
|
||||
fseek(fp, LTOBL(hpe->section_header[i].PointerToRawData), SEEK_SET);
|
||||
*size = LTOBL(hpe->section_header[i].SizeOfRawData);
|
||||
free(data);
|
||||
data = (BYTE *)malloc(*size);
|
||||
if (fread(data, *size, 1, fp) < 1)
|
||||
goto fileError;
|
||||
fclose(fp);
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
fileError:
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
if (data != NULL)
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BYTE *ReadCode2(const char *dataFile, DWORD *size) {
|
||||
BYTE Buf[16], *buf=Buf;
|
||||
FILE *fp = NULL;
|
||||
if ((fp=fopen(dataFile, "rb")) == NULL
|
||||
|| fread(buf, 16, 1, fp ) < 1)
|
||||
goto fileError;
|
||||
*size = LTOBL(*(UINT4 *)buf ^ *(UINT4 *)(buf + 4));
|
||||
if ((int)*size <= 0)
|
||||
goto fileError;
|
||||
buf = (BYTE *)malloc(*size+0x100);
|
||||
if (fread(buf, *size, 1, fp) < 1) {
|
||||
free(buf);
|
||||
goto fileError;
|
||||
}
|
||||
fclose(fp);
|
||||
return buf;
|
||||
|
||||
fileError:
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void check_free() {
|
||||
if (bin_8021x) {
|
||||
free(bin_8021x);
|
||||
bin_8021x = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int check_init(const char *dataFile) {
|
||||
char name[0x100];
|
||||
char *p;
|
||||
check_free();
|
||||
strcpy(name, dataFile);
|
||||
if ((p=strrchr(name, '/')+1) == (void *)1)
|
||||
p = name;
|
||||
strcpy(p, "8021x.exe");
|
||||
if ((bin_8021x=ReadCode(name, &size_8021x)) == NULL
|
||||
&& (bin_8021x=ReadCode2(dataFile, &size_8021x)) == NULL)
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void V2_check(const BYTE *seed, char *final_str) {
|
||||
int i, size = size_8021x / 8;
|
||||
BYTE table[144], *md5Dig, *b8021x = (BYTE *)malloc(size+16);
|
||||
memcpy(b8021x, seed, 16);
|
||||
for (i=0; i<8; i++) {
|
||||
memcpy(b8021x+16, bin_8021x+size*i, size);
|
||||
md5Dig = ComputeHash(b8021x, size+16);
|
||||
table[18*i] = seed[2*i];
|
||||
memcpy(table+18*i+1, md5Dig, 16);
|
||||
table[18*i+17] = seed[2*i+1];
|
||||
}
|
||||
free(b8021x);
|
||||
md5Dig = ComputeHash(table, 144);
|
||||
hex_to_str(md5Dig, final_str, 16, 1);
|
||||
}
|
||||
|
||||
DWORD getVer(const char *file) {
|
||||
FILE *fp;
|
||||
BYTE *data = NULL;
|
||||
int i, j;
|
||||
DWORD size, VirtualAddress;
|
||||
PPE_HEADER_MAP hpe;
|
||||
PIMAGE_RESOURCE_DIRECTORY prd;
|
||||
PIMAGE_RESOURCE_DATA_ENTRY prde;
|
||||
PVS_VERSIONINFO pvs;
|
||||
|
||||
if ((fp=fopen(file, "rb")) == NULL)
|
||||
goto fileError;
|
||||
data = (BYTE *)malloc(0x1000);
|
||||
if (fread(data, 0x1000, 1, fp) < 1)
|
||||
goto fileError;
|
||||
|
||||
hpe = (PPE_HEADER_MAP)(data + LTOBL(((PIMAGE_DOS_HEADER)data)->e_lfanew));
|
||||
for (i=LTOBS(hpe->_head.NumberOfSections)-1; i>=0; i--) {
|
||||
if (strcmp(hpe->section_header[i].Name, ".rsrc") == 0) {
|
||||
fseek(fp, LTOBL(hpe->section_header[i].PointerToRawData), SEEK_SET);
|
||||
size = LTOBL(hpe->section_header[i].SizeOfRawData);
|
||||
VirtualAddress = LTOBL(hpe->section_header[i].VirtualAddress);
|
||||
free(data);
|
||||
data = (BYTE *)malloc(size);
|
||||
if (fread(data, size, 1, fp) < 1)
|
||||
goto fileError;
|
||||
prd = (PIMAGE_RESOURCE_DIRECTORY)data;
|
||||
for (j=0; j<LTOBS(prd->NumberOfIdEntries); j++) {
|
||||
prd->DirectoryEntries[j].Name = LTOBL(prd->DirectoryEntries[j].Name);
|
||||
if (prd->DirectoryEntries[j].Id==16 && prd->DirectoryEntries[j].NameIsString==0) {
|
||||
prd->DirectoryEntries[j].OffsetToData = LTOBL(prd->DirectoryEntries[j].OffsetToData);
|
||||
prd = (PIMAGE_RESOURCE_DIRECTORY)(data+prd->DirectoryEntries[j].OffsetToDirectory);
|
||||
prd->DirectoryEntries[0].OffsetToData = LTOBL(prd->DirectoryEntries[0].OffsetToData);
|
||||
prd = (PIMAGE_RESOURCE_DIRECTORY)(data+prd->DirectoryEntries[0].OffsetToDirectory);
|
||||
prde = (PIMAGE_RESOURCE_DATA_ENTRY)(data+LTOBL(prd->DirectoryEntries[0].OffsetToData));
|
||||
pvs = (PVS_VERSIONINFO)(data+LTOBL(prde->OffsetToData)-VirtualAddress);
|
||||
size = pvs->Value.dwFileVersionMS;
|
||||
fclose(fp);
|
||||
free(data);
|
||||
return size;
|
||||
}
|
||||
}
|
||||
goto fileError;
|
||||
}
|
||||
}
|
||||
|
||||
fileError:
|
||||
if (fp != NULL)
|
||||
fclose(fp);
|
||||
if (data != NULL)
|
||||
free(data);
|
||||
return -1;
|
||||
}
|
||||
|
219
MentoHUST-OpenWrt-ipk/src/mycheck.h
Normal file
219
MentoHUST-OpenWrt-ipk/src/mycheck.h
Normal file
@ -0,0 +1,219 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:mycheck.h
|
||||
* 摘 要:客户端校验算法
|
||||
* 作 者:kkHAIKE
|
||||
*/
|
||||
#ifndef MYCHECK_H
|
||||
#define MYCHECK_H
|
||||
|
||||
#include "types.h"
|
||||
|
||||
typedef struct _IMAGE_DOS_HEADER { // DOS .EXE header
|
||||
WORD e_magic; // Magic number
|
||||
WORD e_cblp; // Bytes on last page of file
|
||||
WORD e_cp; // Pages in file
|
||||
WORD e_crlc; // Relocations
|
||||
WORD e_cparhdr; // Size of header in paragraphs
|
||||
WORD e_minalloc; // Minimum extra paragraphs needed
|
||||
WORD e_maxalloc; // Maximum extra paragraphs needed
|
||||
WORD e_ss; // Initial (relative) SS value
|
||||
WORD e_sp; // Initial SP value
|
||||
WORD e_csum; // Checksum
|
||||
WORD e_ip; // Initial IP value
|
||||
WORD e_cs; // Initial (relative) CS value
|
||||
WORD e_lfarlc; // File address of relocation table
|
||||
WORD e_ovno; // Overlay number
|
||||
WORD e_res[4]; // Reserved words
|
||||
WORD e_oemid; // OEM identifier (for e_oeminfo)
|
||||
WORD e_oeminfo; // OEM information; e_oemid specific
|
||||
WORD e_res2[10]; // Reserved words
|
||||
LONG e_lfanew; // File address of new exe header
|
||||
} IMAGE_DOS_HEADER, *PIMAGE_DOS_HEADER;
|
||||
|
||||
typedef struct _IMAGE_FILE_HEADER {
|
||||
WORD Machine;
|
||||
WORD NumberOfSections;
|
||||
DWORD TimeDateStamp;
|
||||
DWORD PointerToSymbolTable;
|
||||
DWORD NumberOfSymbols;
|
||||
WORD SizeOfOptionalHeader;
|
||||
WORD Characteristics;
|
||||
} IMAGE_FILE_HEADER, *PIMAGE_FILE_HEADER;
|
||||
|
||||
typedef struct _IMAGE_DATA_DIRECTORY {
|
||||
DWORD VirtualAddress;
|
||||
DWORD Size;
|
||||
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
|
||||
|
||||
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
|
||||
typedef struct _IMAGE_OPTIONAL_HEADER {
|
||||
//
|
||||
// Standard fields.
|
||||
//
|
||||
|
||||
WORD Magic;
|
||||
BYTE MajorLinkerVersion;
|
||||
BYTE MinorLinkerVersion;
|
||||
DWORD SizeOfCode;
|
||||
DWORD SizeOfInitializedData;
|
||||
DWORD SizeOfUninitializedData;
|
||||
DWORD AddressOfEntryPoint;
|
||||
DWORD BaseOfCode;
|
||||
DWORD BaseOfData;
|
||||
|
||||
//
|
||||
// NT additional fields.
|
||||
//
|
||||
|
||||
DWORD ImageBase;
|
||||
DWORD SectionAlignment;
|
||||
DWORD FileAlignment;
|
||||
WORD MajorOperatingSystemVersion;
|
||||
WORD MinorOperatingSystemVersion;
|
||||
WORD MajorImageVersion;
|
||||
WORD MinorImageVersion;
|
||||
WORD MajorSubsystemVersion;
|
||||
WORD MinorSubsystemVersion;
|
||||
DWORD Win32VersionValue;
|
||||
DWORD SizeOfImage;
|
||||
DWORD SizeOfHeaders;
|
||||
DWORD CheckSum;
|
||||
WORD Subsystem;
|
||||
WORD DllCharacteristics;
|
||||
DWORD SizeOfStackReserve;
|
||||
DWORD SizeOfStackCommit;
|
||||
DWORD SizeOfHeapReserve;
|
||||
DWORD SizeOfHeapCommit;
|
||||
DWORD LoaderFlags;
|
||||
DWORD NumberOfRvaAndSizes;
|
||||
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
|
||||
} IMAGE_OPTIONAL_HEADER, *PIMAGE_OPTIONAL_HEADER;
|
||||
|
||||
#define IMAGE_SIZEOF_SHORT_NAME 8
|
||||
typedef struct _IMAGE_SECTION_HEADER {
|
||||
char Name[IMAGE_SIZEOF_SHORT_NAME];
|
||||
union {
|
||||
DWORD PhysicalAddress;
|
||||
DWORD VirtualSize;
|
||||
} Misc;
|
||||
DWORD VirtualAddress;
|
||||
DWORD SizeOfRawData;
|
||||
DWORD PointerToRawData;
|
||||
DWORD PointerToRelocations;
|
||||
DWORD PointerToLinenumbers;
|
||||
WORD NumberOfRelocations;
|
||||
WORD NumberOfLinenumbers;
|
||||
DWORD Characteristics;
|
||||
} IMAGE_SECTION_HEADER, *PIMAGE_SECTION_HEADER;
|
||||
|
||||
typedef struct _PE_HEADER_MAP
|
||||
{
|
||||
DWORD signature;
|
||||
IMAGE_FILE_HEADER _head;
|
||||
IMAGE_OPTIONAL_HEADER opt_head;
|
||||
IMAGE_SECTION_HEADER section_header[8];
|
||||
}PE_HEADER_MAP,*PPE_HEADER_MAP;
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY_ENTRY {
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
union {
|
||||
struct {
|
||||
DWORD NameIsString:1;
|
||||
DWORD NameOffset:31;
|
||||
};
|
||||
DWORD Name;
|
||||
struct {
|
||||
WORD Id_unuse;
|
||||
WORD Id;
|
||||
};
|
||||
};
|
||||
union {
|
||||
DWORD OffsetToData;
|
||||
struct {
|
||||
DWORD DataIsDirectory:1;
|
||||
DWORD OffsetToDirectory:31;
|
||||
};
|
||||
};
|
||||
#else
|
||||
union {
|
||||
struct {
|
||||
DWORD NameOffset:31;
|
||||
DWORD NameIsString:1;
|
||||
};
|
||||
DWORD Name;
|
||||
WORD Id;
|
||||
};
|
||||
union {
|
||||
DWORD OffsetToData;
|
||||
struct {
|
||||
DWORD OffsetToDirectory:31;
|
||||
DWORD DataIsDirectory:1;
|
||||
};
|
||||
};
|
||||
#endif
|
||||
} IMAGE_RESOURCE_DIRECTORY_ENTRY, *PIMAGE_RESOURCE_DIRECTORY_ENTRY;
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DIRECTORY {
|
||||
DWORD Characteristics;
|
||||
DWORD TimeDateStamp;
|
||||
WORD MajorVersion;
|
||||
WORD MinorVersion;
|
||||
WORD NumberOfNamedEntries;
|
||||
WORD NumberOfIdEntries;
|
||||
IMAGE_RESOURCE_DIRECTORY_ENTRY DirectoryEntries[];
|
||||
} IMAGE_RESOURCE_DIRECTORY, *PIMAGE_RESOURCE_DIRECTORY;
|
||||
|
||||
typedef struct _IMAGE_RESOURCE_DATA_ENTRY {
|
||||
DWORD OffsetToData;
|
||||
DWORD Size;
|
||||
DWORD CodePage;
|
||||
DWORD Reserved;
|
||||
} IMAGE_RESOURCE_DATA_ENTRY, *PIMAGE_RESOURCE_DATA_ENTRY;
|
||||
|
||||
typedef struct tagVS_FIXEDFILEINFO {
|
||||
DWORD dwSignature; /* e.g. 0xfeef04bd */
|
||||
DWORD dwStrucVersion; /* e.g. 0x00000042 = "0.42" */
|
||||
DWORD dwFileVersionMS; /* e.g. 0x00030075 = "3.75" */
|
||||
DWORD dwFileVersionLS; /* e.g. 0x00000031 = "0.31" */
|
||||
DWORD dwProductVersionMS; /* e.g. 0x00030010 = "3.10" */
|
||||
DWORD dwProductVersionLS; /* e.g. 0x00000031 = "0.31" */
|
||||
DWORD dwFileFlagsMask; /* = 0x3F for version "0.42" */
|
||||
DWORD dwFileFlags; /* e.g. VFF_DEBUG | VFF_PRERELEASE */
|
||||
DWORD dwFileOS; /* e.g. VOS_DOS_WINDOWS16 */
|
||||
DWORD dwFileType; /* e.g. VFT_DRIVER */
|
||||
DWORD dwFileSubtype; /* e.g. VFT2_DRV_KEYBOARD */
|
||||
DWORD dwFileDateMS; /* e.g. 0 */
|
||||
DWORD dwFileDateLS; /* e.g. 0 */
|
||||
} VS_FIXEDFILEINFO;
|
||||
|
||||
typedef struct _VS_VERSIONINFO {
|
||||
WORD wLength;
|
||||
WORD wValueLength;
|
||||
WORD wType;
|
||||
WORD szKey[16];
|
||||
WORD Padding1[1];
|
||||
VS_FIXEDFILEINFO Value;
|
||||
} VS_VERSIONINFO, *PVS_VERSIONINFO;
|
||||
|
||||
#define IMAGE_SCN_CNT_CODE 0x00000020 // Section contains code
|
||||
#define IMAGE_SCN_MEM_EXECUTE 0x20000000 // Section is executable
|
||||
|
||||
#ifdef WORDS_BIGENDIAN
|
||||
#define LTOBS(x) ltobs(x)
|
||||
#define LTOBL(x) ltobl(x)
|
||||
WORD ltobs(WORD x);
|
||||
DWORD ltobl(DWORD x);
|
||||
#else
|
||||
#define LTOBS(x) (x)
|
||||
#define LTOBL(x) (x)
|
||||
#endif
|
||||
|
||||
int check_init(const char *dataFile);
|
||||
void V2_check(const BYTE *seed, char *final_str);
|
||||
void check_free();
|
||||
DWORD getVer(const char *file);
|
||||
|
||||
#endif
|
592
MentoHUST-OpenWrt-ipk/src/myconfig.c
Normal file
592
MentoHUST-OpenWrt-ipk/src/myconfig.c
Normal file
@ -0,0 +1,592 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:myconfig.c
|
||||
* 摘 要:初始化认证参数
|
||||
* 作 者:HustMoon@BYHH
|
||||
* 邮 箱:www.ehust@gmail.com
|
||||
*/
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include "config.h"
|
||||
#else
|
||||
static const char *VERSION = "0.3.1";
|
||||
static const char *PACKAGE_BUGREPORT = "http://code.google.com/p/mentohust/issues/list";
|
||||
#endif
|
||||
|
||||
#include "myconfig.h"
|
||||
#include "myini.h"
|
||||
#include "myfunc.h"
|
||||
#include "dlfunc.h"
|
||||
#include <string.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <fcntl.h>
|
||||
#include <signal.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#define ACCOUNT_SIZE 65 /* 用户名密码长度*/
|
||||
#define NIC_SIZE 16 /* 网卡名最大长度 */
|
||||
#define MAX_PATH 255 /* FILENAME_MAX */
|
||||
#define D_TIMEOUT 8 /* 默认超时间隔 */
|
||||
#define D_ECHOINTERVAL 30 /* 默认心跳间隔 */
|
||||
#define D_RESTARTWAIT 15 /* 默认重连间隔 */
|
||||
#define D_STARTMODE 0 /* 默认组播模式 */
|
||||
#define D_DHCPMODE 0 /* 默认DHCP模式 */
|
||||
#define D_DAEMONMODE 0 /* 默认daemon模式 */
|
||||
#define D_MAXFAIL 0 /* 默认允许失败次数 */
|
||||
|
||||
static const char *D_DHCPSCRIPT = "dhclient"; /* 默认DHCP脚本 */
|
||||
static const char *CFG_FILE = "/etc/mentohust.conf"; /* 配置文件 */
|
||||
static const char *LOG_FILE = "/tmp/mentohust.log"; /* 日志文件 */
|
||||
static const char *LOCK_FILE = "/tmp/mentohust.pid"; /* 锁文件 */
|
||||
#define LOCKMODE (S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH) /* 创建掩码 */
|
||||
|
||||
#ifndef NO_NOTIFY
|
||||
#define D_SHOWNOTIFY 5 /* 默认Show Notify模式 */
|
||||
int showNotify = D_SHOWNOTIFY; /* 显示通知 */
|
||||
#endif
|
||||
|
||||
extern int bufType; /*0内置xrgsu 1内置Win 2仅文件 3文件+校验*/
|
||||
extern u_char version[]; /* 版本 */
|
||||
char userName[ACCOUNT_SIZE] = ""; /* 用户名 */
|
||||
char password[ACCOUNT_SIZE] = ""; /* 密码 */
|
||||
char nic[NIC_SIZE] = ""; /* 网卡名 */
|
||||
char dataFile[MAX_PATH] = ""; /* 数据文件 */
|
||||
char dhcpScript[MAX_PATH] = ""; /* DHCP脚本 */
|
||||
u_int32_t ip = 0; /* 本机IP */
|
||||
u_int32_t mask = 0; /* 子网掩码 */
|
||||
u_int32_t gateway = 0; /* 网关 */
|
||||
u_int32_t dns = 0; /* DNS */
|
||||
u_int32_t pingHost = 0; /* ping */
|
||||
u_char localMAC[6]; /* 本机MAC */
|
||||
u_char destMAC[6]; /* 服务器MAC */
|
||||
unsigned timeout = D_TIMEOUT; /* 超时间隔 */
|
||||
unsigned echoInterval = D_ECHOINTERVAL; /* 心跳间隔 */
|
||||
unsigned restartWait = D_RESTARTWAIT; /* 失败等待 */
|
||||
unsigned startMode = D_STARTMODE; /* 组播模式 */
|
||||
unsigned dhcpMode = D_DHCPMODE; /* DHCP模式 */
|
||||
unsigned maxFail = D_MAXFAIL; /* 允许失败次数 */
|
||||
pcap_t *hPcap = NULL; /* Pcap句柄 */
|
||||
int lockfd = -1; /* 锁文件描述符 */
|
||||
|
||||
static int readFile(int *daemonMode); /* 读取配置文件来初始化 */
|
||||
static void readArg(char argc, char **argv, int *saveFlag, int *exitFlag, int *daemonMode); /* 读取命令行参数来初始化 */
|
||||
static void showHelp(const char *fileName); /* 显示帮助信息 */
|
||||
static int getAdapter(); /* 查找网卡名 */
|
||||
static void printConfig(); /* 显示初始化后的认证参数 */
|
||||
static int openPcap(); /* 初始化pcap、设置过滤器 */
|
||||
static void saveConfig(int daemonMode); /* 保存参数 */
|
||||
static void checkRunning(int exitFlag, int daemonMode); /* 检测是否已运行 */
|
||||
|
||||
#ifndef NO_ENCODE_PASS
|
||||
static const unsigned char base64Tab[] = {"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"};
|
||||
static const char xorRuijie[] = {"~!:?$*<(qw2e5o7i8x12c6m67s98w43d2l45we82q3iuu1z4xle23rt4oxclle34e54u6r8m"};
|
||||
|
||||
static int encodePass(char *dst, const char *osrc) {
|
||||
unsigned char in[3], buf[70];
|
||||
unsigned char *src = buf;
|
||||
int sz = strlen(osrc);
|
||||
int i, len;
|
||||
if (sizeof(xorRuijie) < sz)
|
||||
return -1;
|
||||
for(i=0; i<sz; i++)
|
||||
src[i] = osrc[i] ^ xorRuijie[i];
|
||||
while (sz > 0) {
|
||||
for (len=0, i=0; i<3; i++, sz--) {
|
||||
if (sz > 0) {
|
||||
len++;
|
||||
in[i] = src[i];
|
||||
} else in[i] = 0;
|
||||
}
|
||||
src += 3;
|
||||
if (len) {
|
||||
dst[0] = base64Tab[ in[0] >> 2 ];
|
||||
dst[1] = base64Tab[ ((in[0] & 0x03) << 4) | ((in[1] & 0xf0) >> 4) ];
|
||||
dst[2] = len > 1 ? base64Tab[ ((in[1] & 0x0f) << 2) | ((in[2] & 0xc0) >> 6) ] : '=';
|
||||
dst[3] = len > 2 ? base64Tab[ in[2] & 0x3f ] : '=';
|
||||
dst += 4;
|
||||
}
|
||||
}
|
||||
*dst = '\0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int decodePass(char *dst, const char *src) {
|
||||
unsigned esi = 0, idx = 0;
|
||||
int i=0, j=0, equal=0;
|
||||
for(; src[i]!='\0'; i++) {
|
||||
if (src[i] == '=') {
|
||||
if (++equal > 2)
|
||||
return -1;
|
||||
} else {
|
||||
for(idx=0; base64Tab[idx]!='\0'; idx++) {
|
||||
if(base64Tab[idx] == src[i])
|
||||
break;
|
||||
}
|
||||
if (idx == 64)
|
||||
return -1;
|
||||
esi += idx;
|
||||
}
|
||||
if(i%4 == 3) {
|
||||
dst[j++] = (char)(esi>>16);
|
||||
if(equal < 2)
|
||||
dst[j++] = (char)(esi>>8);
|
||||
if(equal < 1)
|
||||
dst[j++] = (char)esi;
|
||||
esi = 0;
|
||||
equal = 0;
|
||||
}
|
||||
esi <<= 6;
|
||||
}
|
||||
if (i%4!=0 || sizeof(xorRuijie)<j)
|
||||
return -1;
|
||||
for(i=0; i<j; i++)
|
||||
dst[i] ^= xorRuijie[i];
|
||||
dst[j] = '\0';
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
void initConfig(int argc, char **argv)
|
||||
{
|
||||
int saveFlag = 0; /* 是否需要保存参数 */
|
||||
int exitFlag = 0; /* 0Nothing 1退出 2重启 */
|
||||
int daemonMode = D_DAEMONMODE; /* 是否后台运行 */
|
||||
|
||||
printf("\n欢迎使用MentoHUST\t版本: %s\n"
|
||||
"Copyright (C) 2009-2010 HustMoon Studio\n"
|
||||
"人到华中大,有甜亦有辣。明德厚学地,求是创新家。\n"
|
||||
"Bug report to %s\n\n", VERSION, PACKAGE_BUGREPORT);
|
||||
saveFlag = (readFile(&daemonMode)==0 ? 0 : 1);
|
||||
readArg(argc, argv, &saveFlag, &exitFlag, &daemonMode);
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify) {
|
||||
seteuid(getuid());
|
||||
if (load_libnotify() == -1)
|
||||
showNotify = 0;
|
||||
else
|
||||
set_timeout(1000 * showNotify);
|
||||
seteuid(0);
|
||||
}
|
||||
#endif
|
||||
#ifndef NO_DYLOAD
|
||||
if (load_libpcap() == -1) {
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 错误提示", "载入libpcap失败, 请检查该库文件!");
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
#endif
|
||||
if (nic[0] == '\0')
|
||||
{
|
||||
saveFlag = 1;
|
||||
if (getAdapter() == -1) { /* 找不到(第一块)网卡? */
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 错误提示", "找不到网卡!");
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
if (userName[0]=='\0' || password[0]=='\0') /* 未写用户名密码? */
|
||||
{
|
||||
saveFlag = 1;
|
||||
printf("?? 请输入用户名: ");
|
||||
scanf("%s", userName);
|
||||
printf("?? 请输入密码: ");
|
||||
scanf("%s", password);
|
||||
printf("?? 请选择组播地址(0标准 1锐捷私有 2赛尔): ");
|
||||
scanf("%u", &startMode);
|
||||
startMode %= 3;
|
||||
printf("?? 请选择DHCP方式(0不使用 1二次认证 2认证后 3认证前): ");
|
||||
scanf("%u", &dhcpMode);
|
||||
dhcpMode %= 4;
|
||||
}
|
||||
checkRunning(exitFlag, daemonMode);
|
||||
if (startMode%3==2 && gateway==0) /* 赛尔且未填写网关地址 */
|
||||
{
|
||||
gateway = ip; /* 据说赛尔的网关是ip前三字节,后一字节是2 */
|
||||
((u_char *)&gateway)[3] = 0x02;
|
||||
}
|
||||
if (dhcpScript[0] == '\0') /* 未填写DHCP脚本? */
|
||||
strcpy(dhcpScript, D_DHCPSCRIPT);
|
||||
newBuffer();
|
||||
printConfig();
|
||||
if (fillHeader()==-1 || openPcap()==-1) { /* 获取IP、MAC,打开网卡 */
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 错误提示", "获取MAC地址或打开网卡失败!");
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (saveFlag)
|
||||
saveConfig(daemonMode);
|
||||
}
|
||||
|
||||
static int readFile(int *daemonMode)
|
||||
{
|
||||
char tmp[16];
|
||||
char *buf = loadFile(CFG_FILE);
|
||||
if (buf == NULL)
|
||||
return -1;
|
||||
getString(buf, "MentoHUST", "Username", "", userName, sizeof(userName));
|
||||
getString(buf, "MentoHUST", "Password", "", password, sizeof(password));
|
||||
#ifndef NO_ENCODE_PASS
|
||||
char pass[ACCOUNT_SIZE*4/3];
|
||||
if (password[0] == '\0') {
|
||||
getString(buf, "MentoHUST", "EncodePass", "", pass, sizeof(pass));
|
||||
decodePass(password, pass);
|
||||
} else {
|
||||
encodePass(pass, password);
|
||||
setString(&buf, "MentoHUST", "Password", NULL);
|
||||
setString(&buf, "MentoHUST", "EncodePass", pass);
|
||||
saveFile(buf, CFG_FILE);
|
||||
}
|
||||
#endif
|
||||
getString(buf, "MentoHUST", "Nic", "", nic, sizeof(nic));
|
||||
getString(buf, "MentoHUST", "Datafile", "", dataFile, sizeof(dataFile));
|
||||
getString(buf, "MentoHUST", "DhcpScript", "", dhcpScript, sizeof(dhcpScript));
|
||||
getString(buf, "MentoHUST", "Version", "", tmp, sizeof(tmp));
|
||||
if (strlen(tmp) >= 3) {
|
||||
unsigned ver[2];
|
||||
if (sscanf(tmp, "%u.%u", ver, ver+1)!=EOF && ver[0]!=0) {
|
||||
version[0] = ver[0];
|
||||
version[1] = ver[1];
|
||||
bufType = 1;
|
||||
}
|
||||
}
|
||||
getString(buf, "MentoHUST", "IP", "255.255.255.255", tmp, sizeof(tmp));
|
||||
ip = inet_addr(tmp);
|
||||
getString(buf, "MentoHUST", "Mask", "255.255.255.255", tmp, sizeof(tmp));
|
||||
mask = inet_addr(tmp);
|
||||
getString(buf, "MentoHUST", "Gateway", "0.0.0.0", tmp, sizeof(tmp));
|
||||
gateway = inet_addr(tmp);
|
||||
getString(buf, "MentoHUST", "DNS", "0.0.0.0", tmp, sizeof(tmp));
|
||||
dns = inet_addr(tmp);
|
||||
getString(buf, "MentoHUST", "PingHost", "0.0.0.0", tmp, sizeof(tmp));
|
||||
pingHost = inet_addr(tmp);
|
||||
timeout = getInt(buf, "MentoHUST", "Timeout", D_TIMEOUT) % 100;
|
||||
echoInterval = getInt(buf, "MentoHUST", "EchoInterval", D_ECHOINTERVAL) % 1000;
|
||||
restartWait = getInt(buf, "MentoHUST", "RestartWait", D_RESTARTWAIT) % 100;
|
||||
startMode = getInt(buf, "MentoHUST", "StartMode", D_STARTMODE) % 3;
|
||||
dhcpMode = getInt(buf, "MentoHUST", "DhcpMode", D_DHCPMODE) % 4;
|
||||
#ifndef NO_NOTIFY
|
||||
showNotify = getInt(buf, "MentoHUST", "ShowNotify", D_SHOWNOTIFY) % 21;
|
||||
#endif
|
||||
*daemonMode = getInt(buf, "MentoHUST", "DaemonMode", D_DAEMONMODE) % 4;
|
||||
maxFail = getInt(buf, "MentoHUST", "MaxFail", D_MAXFAIL);
|
||||
free(buf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void readArg(char argc, char **argv, int *saveFlag, int *exitFlag, int *daemonMode)
|
||||
{
|
||||
char *str, c;
|
||||
int i;
|
||||
for (i=1; i<argc; i++)
|
||||
{
|
||||
str = argv[i];
|
||||
if (str[0]!='-' && str[0]!='/')
|
||||
continue;
|
||||
c = str[1];
|
||||
if (c=='h' || c=='?' || strcmp(str, "--help")==0)
|
||||
showHelp(argv[0]);
|
||||
else if (c == 'w')
|
||||
*saveFlag = 1;
|
||||
else if (c == 'k') {
|
||||
if (strlen(str) > 2)
|
||||
*exitFlag = 2;
|
||||
else {
|
||||
*exitFlag = 1;
|
||||
return;
|
||||
}
|
||||
} else if (strlen(str) > 2) {
|
||||
if (c == 'u')
|
||||
strncpy(userName, str+2, sizeof(userName)-1);
|
||||
else if (c == 'p')
|
||||
strncpy(password, str+2, sizeof(password)-1);
|
||||
else if (c == 'n')
|
||||
strncpy(nic, str+2, sizeof(nic)-1);
|
||||
else if (c == 'f')
|
||||
strncpy(dataFile, str+2, sizeof(dataFile)-1);
|
||||
else if (c == 'c')
|
||||
strncpy(dhcpScript, str+2, sizeof(dhcpScript)-1);
|
||||
else if (c=='v' && strlen(str+2)>=3) {
|
||||
unsigned ver[2];
|
||||
if (sscanf(str+2, "%u.%u", ver, ver+1) != EOF) {
|
||||
if (ver[0] == 0)
|
||||
bufType = 0;
|
||||
else {
|
||||
version[0] = ver[0];
|
||||
version[1] = ver[1];
|
||||
bufType = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (c == 'i')
|
||||
ip = inet_addr(str+2);
|
||||
else if (c == 'm')
|
||||
mask = inet_addr(str+2);
|
||||
else if (c == 'g')
|
||||
gateway = inet_addr(str+2);
|
||||
else if (c == 's')
|
||||
dns = inet_addr(str+2);
|
||||
else if (c == 'o')
|
||||
pingHost = inet_addr(str+2);
|
||||
else if (c == 't')
|
||||
timeout = atoi(str+2) % 100;
|
||||
else if (c == 'e')
|
||||
echoInterval = atoi(str+2) % 1000;
|
||||
else if (c == 'r')
|
||||
restartWait = atoi(str+2) % 100;
|
||||
else if (c == 'a')
|
||||
startMode = atoi(str+2) % 3;
|
||||
else if (c == 'd')
|
||||
dhcpMode = atoi(str+2) % 4;
|
||||
#ifndef NO_NOTIFY
|
||||
else if (c == 'y')
|
||||
showNotify = atoi(str+2) % 21;
|
||||
#endif
|
||||
else if (c == 'b')
|
||||
*daemonMode = atoi(str+2) % 4;
|
||||
else if (c == 'l')
|
||||
maxFail = atoi(str+2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void showHelp(const char *fileName)
|
||||
{
|
||||
char *helpString =
|
||||
"用法:\t%s [-选项][参数]\n"
|
||||
"选项:\t-h 显示本帮助信息\n"
|
||||
"\t-k -k(退出程序) 其他(重启程序)\n"
|
||||
"\t-w 保存参数到配置文件\n"
|
||||
"\t-u 用户名\n"
|
||||
"\t-p 密码\n"
|
||||
"\t-n 网卡名\n"
|
||||
"\t-i IP[默认本机IP]\n"
|
||||
"\t-m 子网掩码[默认本机掩码]\n"
|
||||
"\t-g 网关[默认0.0.0.0]\n"
|
||||
"\t-s DNS[默认0.0.0.0]\n"
|
||||
"\t-o Ping主机[默认0.0.0.0,表示关闭该功能]\n"
|
||||
"\t-t 认证超时(秒)[默认8]\n"
|
||||
"\t-e 响应间隔(秒)[默认30]\n"
|
||||
"\t-r 失败等待(秒)[默认15]\n"
|
||||
"\t-l 允许失败次数[默认0,表示无限制]\n"
|
||||
"\t-a 组播地址: 0(标准) 1(锐捷) 2(赛尔) [默认0]\n"
|
||||
"\t-d DHCP方式: 0(不使用) 1(二次认证) 2(认证后) 3(认证前) [默认0]\n"
|
||||
"\t-b 是否后台运行: 0(否) 1(是,关闭输出) 2(是,保留输出) 3(是,输出到文件) [默认0]\n"
|
||||
#ifndef NO_NOTIFY
|
||||
"\t-y 是否显示通知: 0(否) 1~20(是) [默认5]\n"
|
||||
#endif
|
||||
"\t-v 客户端版本号[默认0.00表示兼容xrgsu]\n"
|
||||
"\t-f 自定义数据文件[默认不使用]\n"
|
||||
"\t-c DHCP脚本[默认dhclient]\n"
|
||||
"例如:\t%s -uusername -ppassword -neth0 -i192.168.0.1 -m255.255.255.0 -g0.0.0.0 -s0.0.0.0 -o0.0.0.0 -t8 -e30 -r15 -a0 -d1 -b0 -v4.10 -fdefault.mpf -cdhclient\n"
|
||||
"注意:使用时请确保是以root权限运行!\n\n";
|
||||
printf(helpString, fileName, fileName);
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
|
||||
static int getAdapter()
|
||||
{
|
||||
pcap_if_t *alldevs, *d;
|
||||
int num = 0, avail = 0, i;
|
||||
char errbuf[PCAP_ERRBUF_SIZE];
|
||||
if (pcap_findalldevs(&alldevs, errbuf)==-1 || alldevs==NULL)
|
||||
{
|
||||
printf("!! 查找网卡失败: %s\n", errbuf);
|
||||
return -1;
|
||||
}
|
||||
for (d=alldevs; d!=NULL; d=d->next)
|
||||
{
|
||||
num++;
|
||||
if (!(d->flags & PCAP_IF_LOOPBACK) && strcmp(d->name, "any")!=0)
|
||||
{
|
||||
printf("** 网卡[%d]:\t%s\n", num, d->name);
|
||||
avail++;
|
||||
i = num;
|
||||
}
|
||||
}
|
||||
if (avail == 0)
|
||||
{
|
||||
pcap_freealldevs(alldevs);
|
||||
printf("!! 找不到网卡!\n");
|
||||
return -1;
|
||||
}
|
||||
if (avail > 1)
|
||||
{
|
||||
printf("?? 请选择网卡[1-%d]: ", num);
|
||||
scanf("%d", &i);
|
||||
if (i < 1)
|
||||
i = 1;
|
||||
else if (i > num)
|
||||
i = num;
|
||||
}
|
||||
printf("** 您选择了第[%d]块网卡。\n", i);
|
||||
for (d=alldevs; i>1; d=d->next, i--);
|
||||
strncpy(nic, d->name, sizeof(nic)-1);
|
||||
pcap_freealldevs(alldevs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void printConfig()
|
||||
{
|
||||
char *addr[] = {"标准", "锐捷", "赛尔"};
|
||||
char *dhcp[] = {"不使用", "二次认证", "认证后", "认证前"};
|
||||
printf("** 用户名:\t%s\n", userName);
|
||||
/* printf("** 密码:\t%s\n", password); */
|
||||
printf("** 网卡: \t%s\n", nic);
|
||||
if (gateway)
|
||||
printf("** 网关地址:\t%s\n", formatIP(gateway));
|
||||
if (dns)
|
||||
printf("** DNS地址:\t%s\n", formatIP(dns));
|
||||
if (pingHost)
|
||||
printf("** 智能重连:\t%s\n", formatIP(pingHost));
|
||||
printf("** 认证超时:\t%u秒\n", timeout);
|
||||
printf("** 响应间隔:\t%u秒\n", echoInterval);
|
||||
printf("** 失败等待:\t%u秒\n", restartWait);
|
||||
printf("** 允许失败:\t%u次\n", maxFail);
|
||||
printf("** 组播地址:\t%s\n", addr[startMode]);
|
||||
printf("** DHCP方式:\t%s\n", dhcp[dhcpMode]);
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
printf("** 通知超时:\t%d秒\n", showNotify);
|
||||
#endif
|
||||
if (bufType >= 2)
|
||||
printf("** 数据文件:\t%s\n", dataFile);
|
||||
if (dhcpMode != 0)
|
||||
printf("** DHCP脚本:\t%s\n", dhcpScript);
|
||||
}
|
||||
|
||||
static int openPcap()
|
||||
{
|
||||
char buf[PCAP_ERRBUF_SIZE], *fmt;
|
||||
struct bpf_program fcode;
|
||||
if ((hPcap = pcap_open_live(nic, 2048, 1, 1000, buf)) == NULL)
|
||||
{
|
||||
printf("!! 打开网卡%s失败: %s\n", nic, buf);
|
||||
return -1;
|
||||
}
|
||||
fmt = formatHex(localMAC, 6);
|
||||
#ifndef NO_ARP
|
||||
sprintf(buf, "((ether proto 0x888e and (ether dst %s or ether dst 01:80:c2:00:00:03)) "
|
||||
"or ether proto 0x0806) and not ether src %s", fmt, fmt);
|
||||
#else
|
||||
sprintf(buf, "ether proto 0x888e and (ether dst %s or ether dst 01:80:c2:00:00:03) "
|
||||
"and not ether src %s", fmt, fmt);
|
||||
#endif
|
||||
if (pcap_compile(hPcap, &fcode, buf, 0, 0xffffffff) == -1
|
||||
|| pcap_setfilter(hPcap, &fcode) == -1)
|
||||
{
|
||||
printf("!! 设置pcap过滤器失败: %s\n", pcap_geterr(hPcap));
|
||||
return -1;
|
||||
}
|
||||
pcap_freecode(&fcode);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void saveConfig(int daemonMode)
|
||||
{
|
||||
char *buf = loadFile(CFG_FILE);
|
||||
if (buf == NULL) {
|
||||
buf = (char *)malloc(1);
|
||||
buf[0] = '\0';
|
||||
}
|
||||
setString(&buf, "MentoHUST", "DhcpScript", dhcpScript);
|
||||
setString(&buf, "MentoHUST", "DataFile", dataFile);
|
||||
if (bufType != 0) {
|
||||
char ver[10];
|
||||
sprintf(ver, "%u.%u", version[0], version[1]);
|
||||
setString(&buf, "MentoHUST", "Version", ver);
|
||||
} else
|
||||
setString(&buf, "MentoHUST", "Version", "0.00");
|
||||
#ifndef NO_NOTIFY
|
||||
setInt(&buf, "MentoHUST", "ShowNotify", showNotify);
|
||||
#endif
|
||||
setInt(&buf, "MentoHUST", "DaemonMode", daemonMode);
|
||||
setInt(&buf, "MentoHUST", "DhcpMode", dhcpMode);
|
||||
setInt(&buf, "MentoHUST", "StartMode", startMode);
|
||||
setInt(&buf, "MentoHUST", "MaxFail", maxFail);
|
||||
setInt(&buf, "MentoHUST", "RestartWait", restartWait);
|
||||
setInt(&buf, "MentoHUST", "EchoInterval", echoInterval);
|
||||
setInt(&buf, "MentoHUST", "Timeout", timeout);
|
||||
setString(&buf, "MentoHUST", "PingHost", formatIP(pingHost));
|
||||
setString(&buf, "MentoHUST", "DNS", formatIP(dns));
|
||||
setString(&buf, "MentoHUST", "Gateway", formatIP(gateway));
|
||||
setString(&buf, "MentoHUST", "Mask", formatIP(mask));
|
||||
setString(&buf, "MentoHUST", "IP", formatIP(ip));
|
||||
setString(&buf, "MentoHUST", "Nic", nic);
|
||||
#ifdef NO_ENCODE_PASS
|
||||
setString(&buf, "MentoHUST", "Password", password);
|
||||
#else
|
||||
char pass[ACCOUNT_SIZE*4/3];
|
||||
encodePass(pass, password);
|
||||
setString(&buf, "MentoHUST", "EncodePass", pass);
|
||||
#endif
|
||||
setString(&buf, "MentoHUST", "Username", userName);
|
||||
if (saveFile(buf, CFG_FILE) != 0)
|
||||
printf("!! 保存认证参数到%s失败!\n", CFG_FILE);
|
||||
else
|
||||
printf("** 认证参数已成功保存到%s.\n", CFG_FILE);
|
||||
free(buf);
|
||||
}
|
||||
|
||||
static void checkRunning(int exitFlag, int daemonMode)
|
||||
{
|
||||
struct flock fl;
|
||||
lockfd = open (LOCK_FILE, O_RDWR|O_CREAT, LOCKMODE);
|
||||
if (lockfd < 0) {
|
||||
perror("!! 打开锁文件失败"); /* perror真的很好啊,以前没用它真是太亏了 */
|
||||
goto error_exit;
|
||||
}
|
||||
fl.l_start = 0;
|
||||
fl.l_whence = SEEK_SET;
|
||||
fl.l_len = 0;
|
||||
fl.l_type = F_WRLCK;
|
||||
if (fcntl(lockfd, F_GETLK, &fl) < 0) {
|
||||
perror("!! 获取文件锁失败");
|
||||
goto error_exit;
|
||||
}
|
||||
if (exitFlag) {
|
||||
if (fl.l_type != F_UNLCK) {
|
||||
printf(">> 已发送退出信号给MentoHUST进程(PID=%d).\n", fl.l_pid);
|
||||
if (kill(fl.l_pid, SIGINT) == -1)
|
||||
perror("!! 结束进程失败");
|
||||
}
|
||||
else
|
||||
printf("!! 没有MentoHUST正在运行!\n");
|
||||
if (exitFlag == 1)
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
else if (fl.l_type != F_UNLCK) {
|
||||
printf("!! MentoHUST已经运行(PID=%d)!\n", fl.l_pid);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
if (daemonMode) { /* 貌似我过早进入后台模式了,就给个选项保留输出或者输出到文件吧 */
|
||||
printf(">> 进入后台运行模式,使用参数-k可退出认证。\n");
|
||||
if (daemon(0, (daemonMode+1)%2))
|
||||
perror("!! 后台运行失败");
|
||||
else if (daemonMode == 3) {
|
||||
freopen(LOG_FILE, "w", stdout);
|
||||
freopen(LOG_FILE, "a", stderr);
|
||||
}
|
||||
}
|
||||
fl.l_type = F_WRLCK;
|
||||
fl.l_pid = getpid();
|
||||
if (fcntl(lockfd, F_SETLKW, &fl) < 0) {
|
||||
perror("!! 加锁失败");
|
||||
goto error_exit;
|
||||
}
|
||||
return;
|
||||
|
||||
error_exit:
|
||||
#ifndef NO_NOTIFY
|
||||
if (showNotify)
|
||||
show_notify("MentoHUST - 错误提示", "操作锁文件失败,请检查是否为root权限!");
|
||||
#endif
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
13
MentoHUST-OpenWrt-ipk/src/myconfig.h
Normal file
13
MentoHUST-OpenWrt-ipk/src/myconfig.h
Normal file
@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:myconfig.h
|
||||
* 摘 要:初始化认证参数
|
||||
* 作 者:HustMoon@BYHH
|
||||
*/
|
||||
#ifndef HUSTMOON_MYCONFIG_H
|
||||
#define HUSTMOON_MYCONFIG_H
|
||||
|
||||
void initConfig(int argc, char **argv); /* 初始化配置 */
|
||||
|
||||
#endif
|
522
MentoHUST-OpenWrt-ipk/src/myfunc.c
Normal file
522
MentoHUST-OpenWrt-ipk/src/myfunc.c
Normal file
@ -0,0 +1,522 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:myfunc.c
|
||||
* 摘 要:认证相关算法及方法
|
||||
* 作 者:HustMoon@BYHH
|
||||
*/
|
||||
#include "myfunc.h"
|
||||
#include "md5.h"
|
||||
#include "mycheck.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <unistd.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
#ifndef SIOCGIFHWADDR /* BSD、MacOS */
|
||||
#include <net/if_dl.h>
|
||||
#include <ifaddrs.h>
|
||||
#endif
|
||||
#include <sys/poll.h>
|
||||
|
||||
const u_char STANDARD_ADDR[] = {0x01,0x80,0xC2,0x00,0x00,0x03};
|
||||
const u_char RUIJIE_ADDR[] = {0x01,0xD0,0xF8,0x00,0x00,0x03};
|
||||
static const char *DATAFILE = "/etc/mentohust/"; /* 默认数据文件(目录) */
|
||||
|
||||
static int dataOffset; /* 抓包偏移 */
|
||||
static u_int32_t echoKey = 0, echoNo = 0; /* Echo阶段所需 */
|
||||
u_char *fillBuf = NULL; /* 填充包地址 */
|
||||
int fillSize = 0; /* 填充包大小 */
|
||||
int bufType = 0; /*0内置xrgsu 1内置Win 2仅文件 3文件+校验*/
|
||||
u_char version[2]; /* 版本 */
|
||||
#ifndef NO_ARP
|
||||
u_int32_t rip = 0; /* 实际IP */
|
||||
u_char gateMAC[6]; /* 网关MAC */
|
||||
#endif
|
||||
|
||||
extern char password[];
|
||||
extern char nic[];
|
||||
extern char dataFile[];
|
||||
extern u_int32_t ip, mask, gateway, dns, pingHost;
|
||||
extern u_char localMAC[], destMAC[];
|
||||
extern unsigned startMode, dhcpMode;
|
||||
|
||||
static int checkFile(); /* 检查数据文件 */
|
||||
static int getVersion(); /* 获取8021x.exe版本号 */
|
||||
static int getAddress(); /* 获取网络地址 */
|
||||
static u_char encode(u_char base); /* 锐捷算法,颠倒一个字节的8位 */
|
||||
static void checkSum(u_char *buf); /* 锐捷算法,计算两个字节的检验值 */
|
||||
static int setProperty(u_char type, const u_char *value, int length); /* 设置指定属性 */
|
||||
static int readPacket(int type); /* 读取数据 */
|
||||
static int Check(const u_char *md5Seed); /* 校验算法 */
|
||||
|
||||
char *formatIP(u_int32_t ip)
|
||||
{
|
||||
static char tmp[16];
|
||||
u_char *p = (u_char *)(&ip);
|
||||
sprintf(tmp, "%d.%d.%d.%d", p[0], p[1], p[2], p[3]);
|
||||
return tmp;
|
||||
}
|
||||
|
||||
char *formatHex(const void *buf, int length)
|
||||
{
|
||||
static char hex[385];
|
||||
u_char *p = (u_char *)buf;
|
||||
int i;
|
||||
if (length > 128)
|
||||
length = 128;
|
||||
for (i=0; i<length; i++)
|
||||
sprintf(hex+3*i,"%02x:", p[i]);
|
||||
hex[3*length-1] = '\0';
|
||||
return hex;
|
||||
}
|
||||
|
||||
static int checkFile() {
|
||||
u_char Buf[16], *buf=Buf;
|
||||
FILE *fp = NULL;
|
||||
if ((fp=fopen(dataFile, "rb")) == NULL)
|
||||
goto fileError;
|
||||
if (fread(buf, 16, 1, fp)<1 || memcmp(buf, "HUST", 4)!=0) {
|
||||
fclose(fp);
|
||||
goto fileError;
|
||||
}
|
||||
dataOffset = (int)LTOBL(*(u_int32_t *)buf ^ *(u_int32_t *)(buf + 8)) + 16;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
fillSize = ftell(fp);
|
||||
fclose(fp);
|
||||
if (dataOffset < 16)
|
||||
goto fileError;
|
||||
fillSize = (fillSize - dataOffset) / 2 + 0x17;
|
||||
if (fillSize<0x80 || fillSize>0x397)
|
||||
goto fileError;
|
||||
return 0;
|
||||
|
||||
fileError:
|
||||
if (dataFile[strlen(dataFile)-1] != '/')
|
||||
printf("!! 所选文件%s无效,改用内置数据认证。\n", dataFile);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int getVersion() {
|
||||
char file[0x100], *p;
|
||||
DWORD ver;
|
||||
strcpy(file, dataFile);
|
||||
if ((p=strrchr(file, '/')+1) == (void *)1)
|
||||
p = file;
|
||||
strcpy(p, "8021x.exe");
|
||||
if ((ver=getVer(file)) == (DWORD)-1)
|
||||
return -1;
|
||||
p = (char *)&ver;
|
||||
version[0] = p[2];
|
||||
version[1] = p[0];
|
||||
bufType = 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
void newBuffer()
|
||||
{
|
||||
if (dataFile[0] == '\0')
|
||||
strcpy(dataFile, DATAFILE);
|
||||
getVersion();
|
||||
if (checkFile() == 0)
|
||||
bufType += 2;
|
||||
else fillSize = (bufType==0 ? 0x80 : 0x1d7);
|
||||
fillBuf = (u_char *)malloc(fillSize);
|
||||
}
|
||||
|
||||
static int getAddress()
|
||||
{
|
||||
struct ifreq ifr;
|
||||
#ifndef SIOCGIFHWADDR /* BSD、MacOS */
|
||||
struct ifaddrs *ifap, *p = NULL;
|
||||
struct sockaddr_dl *sdl;
|
||||
#endif
|
||||
int sock = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (sock < 0)
|
||||
{
|
||||
printf("!! 创建套接字失败!\n");
|
||||
return -1;
|
||||
}
|
||||
strcpy(ifr.ifr_name, nic);
|
||||
|
||||
#ifdef SIOCGIFHWADDR
|
||||
if (ioctl(sock, SIOCGIFHWADDR, &ifr) < 0)
|
||||
goto getMACError;
|
||||
memcpy(localMAC, ifr.ifr_hwaddr.sa_data, 6);
|
||||
#else
|
||||
if (getifaddrs(&ifap) == 0)
|
||||
{
|
||||
for (p=ifap; p; p=p->ifa_next)
|
||||
{
|
||||
if (p->ifa_name && strcmp(p->ifa_name, nic)==0)
|
||||
{
|
||||
sdl = (struct sockaddr_dl *)p->ifa_addr;
|
||||
memcpy(localMAC, sdl->sdl_data + sdl->sdl_nlen, 6);
|
||||
break;
|
||||
}
|
||||
}
|
||||
freeifaddrs(ifap);
|
||||
}
|
||||
if (p == NULL)
|
||||
goto getMACError;
|
||||
#endif
|
||||
|
||||
if (startMode == 0)
|
||||
memcpy(destMAC, STANDARD_ADDR, 6);
|
||||
else if (startMode == 1)
|
||||
memcpy(destMAC, RUIJIE_ADDR, 6);
|
||||
|
||||
#ifndef NO_ARP
|
||||
gateMAC[0] = 0xFE;
|
||||
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
|
||||
printf("!! 在网卡%s上获取IP失败!\n", nic);
|
||||
else {
|
||||
rip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
||||
if (gateway!=0 && (startMode%3!=2 || ((u_char *)&gateway)[3]!=0x02))
|
||||
gateMAC[0] = 0xFF;
|
||||
}
|
||||
if (dhcpMode!=0 || ip==-1)
|
||||
ip = rip;
|
||||
#else
|
||||
if (dhcpMode!=0 || ip==-1) {
|
||||
if (ioctl(sock, SIOCGIFADDR, &ifr) < 0)
|
||||
printf("!! 在网卡%s上获取IP失败!\n", nic);
|
||||
else
|
||||
ip = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (dhcpMode!=0 || mask==-1) {
|
||||
if (ioctl(sock, SIOCGIFNETMASK, &ifr) < 0)
|
||||
printf("!! 在网卡%s上获取子网掩码失败!\n", nic);
|
||||
else
|
||||
mask = ((struct sockaddr_in *)&ifr.ifr_addr)->sin_addr.s_addr;
|
||||
}
|
||||
close(sock);
|
||||
|
||||
printf("** 本机MAC:\t%s\n", formatHex(localMAC, 6));
|
||||
printf("** 使用IP:\t%s\n", formatIP(ip));
|
||||
printf("** 子网掩码:\t%s\n", formatIP(mask));
|
||||
return 0;
|
||||
|
||||
getMACError:
|
||||
close(sock);
|
||||
printf("!! 在网卡%s上获取MAC失败!\n", nic);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static u_char encode(u_char base) /* 算法,将一个字节的8位颠倒并取反 */
|
||||
{
|
||||
u_char result = 0;
|
||||
int i;
|
||||
for (i=0; i<8; i++)
|
||||
{
|
||||
result <<= 1;
|
||||
result |= base&0x01;
|
||||
base >>= 1;
|
||||
}
|
||||
return ~result;
|
||||
}
|
||||
|
||||
static void checkSum(u_char *buf) /* 算法,计算两个字节的checksum */
|
||||
{
|
||||
u_char table[] =
|
||||
{
|
||||
0x00,0x00,0x21,0x10,0x42,0x20,0x63,0x30,0x84,0x40,0xA5,0x50,0xC6,0x60,0xE7,0x70,
|
||||
0x08,0x81,0x29,0x91,0x4A,0xA1,0x6B,0xB1,0x8C,0xC1,0xAD,0xD1,0xCE,0xE1,0xEF,0xF1,
|
||||
0x31,0x12,0x10,0x02,0x73,0x32,0x52,0x22,0xB5,0x52,0x94,0x42,0xF7,0x72,0xD6,0x62,
|
||||
0x39,0x93,0x18,0x83,0x7B,0xB3,0x5A,0xA3,0xBD,0xD3,0x9C,0xC3,0xFF,0xF3,0xDE,0xE3,
|
||||
0x62,0x24,0x43,0x34,0x20,0x04,0x01,0x14,0xE6,0x64,0xC7,0x74,0xA4,0x44,0x85,0x54,
|
||||
0x6A,0xA5,0x4B,0xB5,0x28,0x85,0x09,0x95,0xEE,0xE5,0xCF,0xF5,0xAC,0xC5,0x8D,0xD5,
|
||||
0x53,0x36,0x72,0x26,0x11,0x16,0x30,0x06,0xD7,0x76,0xF6,0x66,0x95,0x56,0xB4,0x46,
|
||||
0x5B,0xB7,0x7A,0xA7,0x19,0x97,0x38,0x87,0xDF,0xF7,0xFE,0xE7,0x9D,0xD7,0xBC,0xC7,
|
||||
0xC4,0x48,0xE5,0x58,0x86,0x68,0xA7,0x78,0x40,0x08,0x61,0x18,0x02,0x28,0x23,0x38,
|
||||
0xCC,0xC9,0xED,0xD9,0x8E,0xE9,0xAF,0xF9,0x48,0x89,0x69,0x99,0x0A,0xA9,0x2B,0xB9,
|
||||
0xF5,0x5A,0xD4,0x4A,0xB7,0x7A,0x96,0x6A,0x71,0x1A,0x50,0x0A,0x33,0x3A,0x12,0x2A,
|
||||
0xFD,0xDB,0xDC,0xCB,0xBF,0xFB,0x9E,0xEB,0x79,0x9B,0x58,0x8B,0x3B,0xBB,0x1A,0xAB,
|
||||
0xA6,0x6C,0x87,0x7C,0xE4,0x4C,0xC5,0x5C,0x22,0x2C,0x03,0x3C,0x60,0x0C,0x41,0x1C,
|
||||
0xAE,0xED,0x8F,0xFD,0xEC,0xCD,0xCD,0xDD,0x2A,0xAD,0x0B,0xBD,0x68,0x8D,0x49,0x9D,
|
||||
0x97,0x7E,0xB6,0x6E,0xD5,0x5E,0xF4,0x4E,0x13,0x3E,0x32,0x2E,0x51,0x1E,0x70,0x0E,
|
||||
0x9F,0xFF,0xBE,0xEF,0xDD,0xDF,0xFC,0xCF,0x1B,0xBF,0x3A,0xAF,0x59,0x9F,0x78,0x8F,
|
||||
0x88,0x91,0xA9,0x81,0xCA,0xB1,0xEB,0xA1,0x0C,0xD1,0x2D,0xC1,0x4E,0xF1,0x6F,0xE1,
|
||||
0x80,0x10,0xA1,0x00,0xC2,0x30,0xE3,0x20,0x04,0x50,0x25,0x40,0x46,0x70,0x67,0x60,
|
||||
0xB9,0x83,0x98,0x93,0xFB,0xA3,0xDA,0xB3,0x3D,0xC3,0x1C,0xD3,0x7F,0xE3,0x5E,0xF3,
|
||||
0xB1,0x02,0x90,0x12,0xF3,0x22,0xD2,0x32,0x35,0x42,0x14,0x52,0x77,0x62,0x56,0x72,
|
||||
0xEA,0xB5,0xCB,0xA5,0xA8,0x95,0x89,0x85,0x6E,0xF5,0x4F,0xE5,0x2C,0xD5,0x0D,0xC5,
|
||||
0xE2,0x34,0xC3,0x24,0xA0,0x14,0x81,0x04,0x66,0x74,0x47,0x64,0x24,0x54,0x05,0x44,
|
||||
0xDB,0xA7,0xFA,0xB7,0x99,0x87,0xB8,0x97,0x5F,0xE7,0x7E,0xF7,0x1D,0xC7,0x3C,0xD7,
|
||||
0xD3,0x26,0xF2,0x36,0x91,0x06,0xB0,0x16,0x57,0x66,0x76,0x76,0x15,0x46,0x34,0x56,
|
||||
0x4C,0xD9,0x6D,0xC9,0x0E,0xF9,0x2F,0xE9,0xC8,0x99,0xE9,0x89,0x8A,0xB9,0xAB,0xA9,
|
||||
0x44,0x58,0x65,0x48,0x06,0x78,0x27,0x68,0xC0,0x18,0xE1,0x08,0x82,0x38,0xA3,0x28,
|
||||
0x7D,0xCB,0x5C,0xDB,0x3F,0xEB,0x1E,0xFB,0xF9,0x8B,0xD8,0x9B,0xBB,0xAB,0x9A,0xBB,
|
||||
0x75,0x4A,0x54,0x5A,0x37,0x6A,0x16,0x7A,0xF1,0x0A,0xD0,0x1A,0xB3,0x2A,0x92,0x3A,
|
||||
0x2E,0xFD,0x0F,0xED,0x6C,0xDD,0x4D,0xCD,0xAA,0xBD,0x8B,0xAD,0xE8,0x9D,0xC9,0x8D,
|
||||
0x26,0x7C,0x07,0x6C,0x64,0x5C,0x45,0x4C,0xA2,0x3C,0x83,0x2C,0xE0,0x1C,0xC1,0x0C,
|
||||
0x1F,0xEF,0x3E,0xFF,0x5D,0xCF,0x7C,0xDF,0x9B,0xAF,0xBA,0xBF,0xD9,0x8F,0xF8,0x9F,
|
||||
0x17,0x6E,0x36,0x7E,0x55,0x4E,0x74,0x5E,0x93,0x2E,0xB2,0x3E,0xD1,0x0E,0xF0,0x1E
|
||||
};
|
||||
u_char *checkSum = buf + 0x15;
|
||||
int i, index;
|
||||
for (i=0; i<0x15; i++)
|
||||
{
|
||||
index = checkSum[0] ^ buf[i];
|
||||
checkSum[0] = checkSum[1] ^ table[index*2+1];
|
||||
checkSum[1] = table[index*2];
|
||||
}
|
||||
for (i=0; i<0x17; i++)
|
||||
buf[i] = encode(buf[i]);
|
||||
}
|
||||
|
||||
int fillHeader()
|
||||
{
|
||||
if (getAddress() == -1)
|
||||
return -1;
|
||||
memset(fillBuf, 0, fillSize);
|
||||
fillBuf[0x02] = 0x13;
|
||||
fillBuf[0x03] = 0x11;
|
||||
if (dhcpMode != 0)
|
||||
fillBuf[0x04] = 0x01; /* DHCP位,使用1、不使用0 */
|
||||
memcpy(fillBuf+0x05, &ip, 4);
|
||||
memcpy(fillBuf+0x09, &mask, 4);
|
||||
memcpy(fillBuf+0x0D, &gateway, 4);
|
||||
memcpy(fillBuf+0x11, &dns, 4);
|
||||
checkSum(fillBuf);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int setProperty(u_char type, const u_char *value, int length)
|
||||
{
|
||||
u_char *p = fillBuf+0x46, *end = fillBuf+fillSize-length-8; /* 形如1a 28 00 00 13 11 17 22,至少8个字节 */
|
||||
while (p < end)
|
||||
{
|
||||
if (*p == 0x1a) /* 有些老版本没有前两个字节,包括xrgsu */
|
||||
p += 2;
|
||||
if (p[4] == type)
|
||||
{
|
||||
memcpy(p+4+p[5]-length, value, length);
|
||||
return 0;
|
||||
}
|
||||
p += p[5] + 4;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int readPacket(int type)
|
||||
{
|
||||
u_char dhcp[] = {0x00};
|
||||
FILE *fp = fopen(dataFile, "rb");
|
||||
if (fp == NULL)
|
||||
goto fileError;
|
||||
type %= 2; /* 偶数读Start包,奇数读Md5包 */
|
||||
fseek(fp, dataOffset+(fillSize-0x17)*type, SEEK_SET);
|
||||
if (fread(fillBuf+0x17, fillSize-0x17, 1, fp) < 1) /* 前0x17字节是地址及校验值 */
|
||||
{
|
||||
fclose(fp);
|
||||
goto fileError;
|
||||
}
|
||||
fclose(fp);
|
||||
if (dhcpMode == 1) /* 二次认证第一次 */
|
||||
dhcp[0] = 0x01;
|
||||
setProperty(0x18, dhcp, 1);
|
||||
setProperty(0x2D, localMAC, 6);
|
||||
if (bufType == 3)
|
||||
memcpy(fillBuf+0x3b, version, 2);
|
||||
return 0;
|
||||
|
||||
fileError:
|
||||
printf("!! 所选文件%s无效,改用内置数据认证。\n", dataFile);
|
||||
bufType -= 2;
|
||||
if (bufType==1 && fillSize<0x1d7) {
|
||||
free(fillBuf);
|
||||
fillSize = 0x1d7;
|
||||
fillBuf = (u_char *)malloc(fillSize);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void fillStartPacket()
|
||||
{
|
||||
if (bufType <= 1) { /* 使用xrgsu? */
|
||||
const u_char packet0[] = {
|
||||
0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00,0x00,0x13,0x11,0x00,0x28,0x1a,
|
||||
0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x91,0x66,0x64,0x93,0x67,0x60,0x65,0x62,0x62,
|
||||
0x94,0x61,0x69,0x67,0x63,0x91,0x93,0x92,0x68,0x66,0x93,0x91,0x66,0x95,0x65,0xaa,
|
||||
0xdc,0x64,0x98,0x96,0x6a,0x9d,0x66,0x00,0x00,0x13,0x11,0x18,0x06,0x02,0x00,0x00
|
||||
};
|
||||
const u_char packet1[] = {
|
||||
0x00,0x00,0x13,0x11,0x38,0x30,0x32,0x31,0x78,0x2e,0x65,0x78,0x65,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x04,0x0a,0x00,0x02,0x00,0x00,0x00,0x13,0x11,0x01,0x8c,0x1a,
|
||||
0x28,0x00,0x00,0x13,0x11,0x17,0x22,0x36,0x38,0x44,0x43,0x31,0x32,0x33,0x42,0x37,
|
||||
0x45,0x42,0x32,0x33,0x39,0x46,0x32,0x33,0x41,0x38,0x43,0x30,0x30,0x30,0x33,0x38,
|
||||
0x38,0x34,0x39,0x38,0x36,0x33,0x39,0x1a,0x0c,0x00,0x00,0x13,0x11,0x18,0x06,0x00,
|
||||
0x00,0x00,0x00,0x1a,0x0e,0x00,0x00,0x13,0x11,0x2d,0x08,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x1a,0x08,0x00,0x00,0x13,0x11,0x2f,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x35,
|
||||
0x03,0x01,0x1a,0x18,0x00,0x00,0x13,0x11,0x36,0x12,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x18,0x00,0x00,0x13,0x11,
|
||||
0x38,0x12,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xfe,0x86,
|
||||
0x13,0x4c,0x1a,0x88,0x00,0x00,0x13,0x11,0x4d,0x82,0x36,0x38,0x64,0x63,0x31,0x32,
|
||||
0x33,0x62,0x30,0x37,0x65,0x62,0x32,0x33,0x39,0x66,0x32,0x33,0x61,0x38,0x30,0x64,
|
||||
0x63,0x66,0x32,0x35,0x38,0x37,0x35,0x64,0x30,0x35,0x37,0x37,0x30,0x63,0x37,0x32,
|
||||
0x31,0x65,0x34,0x35,0x36,0x34,0x35,0x65,0x35,0x33,0x37,0x61,0x62,0x33,0x35,0x31,
|
||||
0x62,0x62,0x36,0x33,0x31,0x35,0x35,0x61,0x65,0x31,0x36,0x32,0x36,0x31,0x36,0x37,
|
||||
0x65,0x62,0x30,0x39,0x32,0x32,0x33,0x65,0x32,0x61,0x30,0x61,0x37,0x38,0x30,0x33,
|
||||
0x31,0x31,0x36,0x31,0x61,0x63,0x30,0x39,0x64,0x61,0x32,0x64,0x63,0x30,0x37,0x33,
|
||||
0x36,0x39,0x33,0x61,0x34,0x66,0x35,0x61,0x32,0x39,0x32,0x38,0x36,0x37,0x35,0x31,
|
||||
0x66,0x39,0x37,0x66,0x34,0x64,0x30,0x34,0x36,0x38,0x1a,0x28,0x00,0x00,0x13,0x11,
|
||||
0x39,0x22,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x1a,0x48,0x00,0x00,0x13,0x11,0x54,0x42,0x48,0x55,0x53,0x54,0x4d,0x4f,
|
||||
0x4f,0x4e,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1a,0x08,0x00,0x00,0x13,0x11,
|
||||
0x55,0x02,0x1a,0x09,0x00,0x00,0x13,0x11,0x62,0x03,0x00,0x00,0x00,0x00,0x00,0x00
|
||||
};
|
||||
u_char dhcp[] = {0x00};
|
||||
if (dhcpMode == 1) /* 二次认证第一次 */
|
||||
dhcp[0] = 0x01;
|
||||
if (bufType == 1) {
|
||||
memcpy(fillBuf+0x17, packet1, sizeof(packet1));
|
||||
memcpy(fillBuf+0x3b, version, 2);
|
||||
} else
|
||||
memcpy(fillBuf+0x17, packet0, sizeof(packet0));
|
||||
setProperty(0x18, dhcp, 1);
|
||||
setProperty(0x2D, localMAC, 6);
|
||||
}
|
||||
else if (readPacket(0) == -1) /* 读取数据失败就用默认的填充 */
|
||||
fillStartPacket();
|
||||
}
|
||||
|
||||
void fillMd5Packet(const u_char *md5Seed)
|
||||
{
|
||||
if (bufType <= 1) { /* 不使用数据包? */
|
||||
/* xrgsu的Md5包与Start包只有一个字节的差异,若以其他版本为基础,可进一步区别对待 */
|
||||
fillStartPacket();
|
||||
if (bufType == 1)
|
||||
Check(md5Seed);
|
||||
} else {
|
||||
if (readPacket(1) == -1)
|
||||
fillMd5Packet(md5Seed);
|
||||
else
|
||||
Check(md5Seed);
|
||||
}
|
||||
echoNo = 0x0000102B; /* 初始化echoNo */
|
||||
}
|
||||
|
||||
static int Check(const u_char *md5Seed) /* 客户端校验 */
|
||||
{
|
||||
char final_str[129];
|
||||
int value;
|
||||
printf("** 客户端版本:\t%d.%d\n", fillBuf[0x3B], fillBuf[0x3C]);
|
||||
printf("** MD5种子:\t%s\n", formatHex(md5Seed, 16));
|
||||
value = check_init(dataFile);
|
||||
if (value == -1) {
|
||||
printf("!! 缺少8021x.exe信息,客户端校验无法继续!\n");
|
||||
return 1;
|
||||
}
|
||||
V2_check(md5Seed, final_str);
|
||||
printf("** V2校验值:\t%s\n", final_str);
|
||||
setProperty(0x17, (u_char *)final_str, 32);
|
||||
check_free();
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fillEchoPacket(u_char *echoBuf)
|
||||
{
|
||||
int i;
|
||||
u_int32_t dd1=htonl(echoKey + echoNo), dd2=htonl(echoNo);
|
||||
u_char *bt1=(u_char *)&dd1, *bt2=(u_char *)&dd2;
|
||||
echoNo++;
|
||||
for (i=0; i<4; i++)
|
||||
{
|
||||
echoBuf[0x18+i] = encode(bt1[i]);
|
||||
echoBuf[0x22+i] = encode(bt2[i]);
|
||||
}
|
||||
}
|
||||
|
||||
void getEchoKey(const u_char *capBuf)
|
||||
{
|
||||
int i, offset = 0x1c+capBuf[0x1b]+0x69+24; /* 通过比较了大量抓包,通用的提取点就是这样的 */
|
||||
u_char *base;
|
||||
echoKey = ntohl(*(u_int32_t *)(capBuf+offset));
|
||||
base = (u_char *)(&echoKey);
|
||||
for (i=0; i<4; i++)
|
||||
base[i] = encode(base[i]);
|
||||
}
|
||||
|
||||
u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen)
|
||||
{
|
||||
u_char md5Src[80];
|
||||
int md5Len = strlen(password);
|
||||
md5Src[0] = id;
|
||||
memcpy(md5Src+1, password, md5Len);
|
||||
md5Len++;
|
||||
if (startMode % 3 == 2) /* 赛尔? */
|
||||
{
|
||||
memcpy(md5Src+md5Len, "xxghlmxhzb", 10);
|
||||
md5Len += 10;
|
||||
}
|
||||
memcpy(md5Src+md5Len, md5Seed, seedLen);
|
||||
md5Len += seedLen;
|
||||
return ComputeHash(md5Src, md5Len);
|
||||
}
|
||||
|
||||
void fillCernetAddr(u_char *buf)
|
||||
{
|
||||
memcpy(buf+0x18, &ip, 4);
|
||||
memcpy(buf+0x1C, &mask, 4);
|
||||
memcpy(buf+0x20, &gateway, 4);
|
||||
memset(buf+0x24, 0, 4); /* memcpy(buf+0x24, &dns, 4); */
|
||||
}
|
||||
|
||||
int isOnline()
|
||||
{
|
||||
u_char echoPacket[] =
|
||||
{
|
||||
0x08,0x00,0x61,0xb2,0x02,0x00,0x01,0x00,0x57,0x65,0x6C,0x63,0x6F,0x6D,0x65,0x20,
|
||||
0x74,0x6F,0x20,0x4D,0x65,0x6E,0x74,0x6F,0x48,0x55,0x53,0x54,0x21,0x0A,0x43,0x6F,
|
||||
0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x32,0x30,0x30,0x39,
|
||||
0x20,0x48,0x75,0x73,0x74,0x4D,0x6F,0x6F,0x6E,0x20,0x53,0x74,0x75,0x64,0x69,0x6F
|
||||
};
|
||||
int sock=-1, rtVal, t;
|
||||
struct pollfd pfd;
|
||||
struct sockaddr_in dest;
|
||||
if (pingHost == 0)
|
||||
return 0;
|
||||
memset(&dest, 0, sizeof(dest));
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_addr.s_addr = pingHost;
|
||||
if ((sock=socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) < 0)
|
||||
goto pingError;
|
||||
pfd.fd = sock;
|
||||
pfd.events = POLLIN;
|
||||
for (t=1; t<=3; t++) {
|
||||
if (sendto(sock, echoPacket, sizeof(echoPacket), 0,
|
||||
(struct sockaddr *)&dest, sizeof(dest)) < 0)
|
||||
goto pingError;
|
||||
rtVal = poll(&pfd, 1, t*1000);
|
||||
if (rtVal == -1)
|
||||
goto pingError;
|
||||
if (rtVal > 0) {
|
||||
close(sock);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
close(sock);
|
||||
return -1;
|
||||
|
||||
pingError:
|
||||
perror("!! Ping主机出错,关闭该功能");
|
||||
if (sock != -1)
|
||||
close(sock);
|
||||
pingHost = 0;
|
||||
return 0;
|
||||
}
|
26
MentoHUST-OpenWrt-ipk/src/myfunc.h
Normal file
26
MentoHUST-OpenWrt-ipk/src/myfunc.h
Normal file
@ -0,0 +1,26 @@
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:myfunc.h
|
||||
* 摘 要:认证相关算法及方法
|
||||
* 作 者:HustMoon@BYHH
|
||||
*/
|
||||
#ifndef HUSTMOON_MYFUNC_H
|
||||
#define HUSTMOON_MYFUNC_H
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
char *formatIP(u_int32_t ip); /* 格式化IP */
|
||||
char *formatHex(const void *buf, int length); /* 格式化成十六进制形式 */
|
||||
void newBuffer(); /* 检测数据文件有效性并分配内存 */
|
||||
int fillHeader(); /* 填充网络地址及校验值部分 */
|
||||
void fillStartPacket(); /* 填充Start包 */
|
||||
void fillMd5Packet(const u_char *md5Seed); /* 填充Md5包 */
|
||||
void fillEchoPacket(u_char *buf); /* 填充Echo包 */
|
||||
void getEchoKey(const u_char *capBuf); /* 获取EchoKey */
|
||||
u_char *checkPass(u_char id, const u_char *md5Seed, int seedLen); /* 计算密码的md5 */
|
||||
void fillCernetAddr(u_char *buf); /* 填充赛尔网络地址 */
|
||||
int isOnline(); /* ping主机判断是否掉线 */
|
||||
|
||||
#endif
|
||||
|
203
MentoHUST-OpenWrt-ipk/src/myini.c
Normal file
203
MentoHUST-OpenWrt-ipk/src/myini.c
Normal file
@ -0,0 +1,203 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:myini.c
|
||||
* 摘 要:读取ini文件+写入ini文件
|
||||
* 作 者:HustMoon@BYHH
|
||||
* 修 改:2009.10.8
|
||||
*/
|
||||
#include "myini.h"
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define NOT_COMMENT(c) (c!=';' && c!='#') /* 不是注释行 */
|
||||
|
||||
#ifndef strnicmp
|
||||
#define strnicmp strncasecmp
|
||||
#endif
|
||||
|
||||
static void getLine(const char *buf, int inStart, int *lineStart, int *lineEnd);
|
||||
static int findKey(const char *buf, const char *section, const char *key,
|
||||
int *sectionStart, int *valueStart, unsigned long *valueSize);
|
||||
static int getSection(const char *buf, int inStart);
|
||||
|
||||
char *loadFile(const char *fileName)
|
||||
{
|
||||
FILE *fp = NULL;
|
||||
long size = 0;
|
||||
char *buf = NULL;
|
||||
if ((fp=fopen(fileName, "rb")) == NULL)
|
||||
return NULL;
|
||||
fseek(fp, 0, SEEK_END);
|
||||
size = ftell(fp);
|
||||
rewind(fp);
|
||||
buf = (char *)malloc(size+1);
|
||||
buf[size] = '\0';
|
||||
if (fread(buf, size, 1, fp) < 1)
|
||||
{
|
||||
free(buf);
|
||||
buf = NULL;
|
||||
}
|
||||
fclose(fp);
|
||||
return buf;
|
||||
}
|
||||
|
||||
static void getLine(const char *buf, int inStart, int *lineStart, int *lineEnd)
|
||||
{
|
||||
int start, end;
|
||||
for (start=inStart; buf[start]==' ' || buf[start]=='\t' || buf[start]=='\r' || buf[start]=='\n'; start++);
|
||||
for (end=start; buf[end]!='\r' && buf[end]!='\n' && buf[end]!='\0'; end++);
|
||||
*lineStart = start;
|
||||
*lineEnd = end;
|
||||
}
|
||||
|
||||
static int findKey(const char *buf, const char *section, const char *key,
|
||||
int *sectionStart, int *valueStart, unsigned long *valueSize)
|
||||
{
|
||||
int lineStart, lineEnd, i;
|
||||
for (*sectionStart=-1, lineEnd=0; buf[lineEnd]!='\0'; )
|
||||
{
|
||||
getLine(buf, lineEnd, &lineStart, &lineEnd);
|
||||
if (buf[lineStart] == '[')
|
||||
{
|
||||
for (i=++lineStart; i<lineEnd && buf[i]!=']'; i++);
|
||||
if (i<lineEnd && strnicmp(buf+lineStart, section, i-lineStart)==0) /* 找到Section? */
|
||||
{
|
||||
*sectionStart = lineStart-1;
|
||||
if (key == NULL)
|
||||
return -1;
|
||||
}
|
||||
else if (*sectionStart != -1) /* 找到Section但未找到Key */
|
||||
return -1;
|
||||
}
|
||||
else if (*sectionStart!=-1 && NOT_COMMENT(buf[lineStart])) /* 找到Section且该行不是注释 */
|
||||
{
|
||||
for (i=lineStart+1; i<lineEnd && buf[i]!='='; i++);
|
||||
if (i<lineEnd && strnicmp(buf+lineStart, key, i-lineStart)==0) /* 找到Key? */
|
||||
{
|
||||
*valueStart = i + 1;
|
||||
*valueSize = lineEnd - *valueStart;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int getString(const char *buf, const char *section, const char *key,
|
||||
const char *defaultValue, char *value, unsigned long size)
|
||||
{
|
||||
int sectionStart, valueStart;
|
||||
unsigned long valueSize;
|
||||
|
||||
if (findKey(buf, section, key, §ionStart, &valueStart, &valueSize)!=0 || valueSize==0) /* 未找到? */
|
||||
{
|
||||
strncpy(value, defaultValue, size);
|
||||
return -1;
|
||||
}
|
||||
if (size-1 < valueSize) /* 找到但太长? */
|
||||
valueSize = size - 1;
|
||||
memset(value, 0, size);
|
||||
strncpy(value, buf+valueStart, valueSize);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int getInt(const char *buf, const char *section, const char *key, int defaultValue)
|
||||
{
|
||||
char value[21] = {0};
|
||||
getString(buf, section, key, "", value, sizeof(value));
|
||||
if (value[0] == '\0') /* 找不到或找到但为空? */
|
||||
return defaultValue;
|
||||
return atoi(value);
|
||||
}
|
||||
|
||||
void setString(char **buf, const char *section, const char *key, const char *value)
|
||||
{
|
||||
int sectionStart, valueStart;
|
||||
unsigned long valueSize;
|
||||
char *newBuf = NULL;
|
||||
|
||||
if (findKey(*buf, section, key, §ionStart, &valueStart, &valueSize) == 0) /* 找到key */
|
||||
{
|
||||
if (value == NULL) /* 删除key? */
|
||||
memmove(*buf+valueStart-strlen(key)-1, *buf+valueStart+valueSize,
|
||||
strlen(*buf)+1-valueStart-valueSize);
|
||||
else /* 修改key */
|
||||
{
|
||||
newBuf = (char *)malloc(strlen(*buf)-valueSize+strlen(value)+1);
|
||||
memcpy(newBuf, *buf, valueStart);
|
||||
strcpy(newBuf+valueStart, value);
|
||||
strcpy(newBuf+valueStart+strlen(value), *buf+valueStart+valueSize);
|
||||
free(*buf);
|
||||
*buf = newBuf;
|
||||
}
|
||||
}
|
||||
else if (sectionStart != -1) /* 找到section,找不到key */
|
||||
{
|
||||
if (key == NULL) /* 删除section? */
|
||||
{
|
||||
valueStart = getSection(*buf, sectionStart+3);
|
||||
if (valueStart <= sectionStart) /* 后面没有section */
|
||||
(*buf)[sectionStart] = '\0';
|
||||
else
|
||||
memmove(*buf+sectionStart, *buf+valueStart, strlen(*buf)+1-valueStart);
|
||||
}
|
||||
else if (value != NULL) /* 不是要删除key */
|
||||
{
|
||||
newBuf = (char *)malloc(strlen(*buf)+strlen(key)+strlen(value)+4);
|
||||
valueSize = sectionStart+strlen(section)+2;
|
||||
memcpy(newBuf, *buf, valueSize);
|
||||
sprintf(newBuf+valueSize, "\n%s=%s", key, value);
|
||||
strcpy(newBuf+strlen(newBuf), *buf+valueSize);
|
||||
free(*buf);
|
||||
*buf = newBuf;
|
||||
}
|
||||
}
|
||||
else /* 找不到section? */
|
||||
{
|
||||
if (key!=NULL && value!=NULL)
|
||||
{
|
||||
newBuf = (char *)malloc(strlen(*buf)+strlen(section)+strlen(key)+strlen(value)+8);
|
||||
strcpy(newBuf, *buf);
|
||||
sprintf(newBuf+strlen(newBuf), "\n[%s]\n%s=%s", section, key, value);
|
||||
free(*buf);
|
||||
*buf = newBuf;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static int getSection(const char *buf, int inStart)
|
||||
{
|
||||
int lineStart, lineEnd, i;
|
||||
for (lineEnd=inStart; buf[lineEnd]!='\0'; )
|
||||
{
|
||||
getLine(buf, lineEnd, &lineStart, &lineEnd);
|
||||
if (buf[lineStart] == '[')
|
||||
{
|
||||
for (i=lineStart+1; i<lineEnd && buf[i]!=']'; i++);
|
||||
if (i < lineEnd)
|
||||
return lineStart;
|
||||
}
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
void setInt(char **buf, const char *section, const char *key, int value)
|
||||
{
|
||||
char svalue[21];
|
||||
sprintf(svalue, "%d", value);
|
||||
setString(buf, section, key, svalue);
|
||||
}
|
||||
|
||||
int saveFile(const char *buf, const char *fileName)
|
||||
{
|
||||
FILE *fp;
|
||||
int result;
|
||||
|
||||
if ((fp=fopen(fileName, "wb")) == NULL)
|
||||
return -1;
|
||||
result = fwrite(buf, strlen(buf), 1, fp)<1 ? -1 : 0;
|
||||
fclose(fp);
|
||||
return result;
|
||||
}
|
32
MentoHUST-OpenWrt-ipk/src/myini.h
Normal file
32
MentoHUST-OpenWrt-ipk/src/myini.h
Normal file
@ -0,0 +1,32 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:myini.h
|
||||
* 摘 要:读取ini文件+写入ini文件
|
||||
* 作 者:HustMoon@BYHH
|
||||
* 修 改:2009.10.8
|
||||
*/
|
||||
#ifndef HUSTMOON_MYINI_H
|
||||
#define HUSTMOON_MYINI_H
|
||||
|
||||
#include <stdlib.h> /* for free() */
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C"
|
||||
{
|
||||
#endif
|
||||
|
||||
char *loadFile(const char *fileName); /* 读取文件 */
|
||||
int getString(const char *buf, const char *section, const char *key,
|
||||
const char *defaultValue, char *value, unsigned long size); /* 读取字符串 */
|
||||
int getInt(const char *buf, const char *section, const char *key, int defaultValue); /* 读取整数 */
|
||||
void setString(char **buf, const char *section, const char *key, const char *value); /* 设置字符串,value=NULL则删除key,key=NULL则删除section */
|
||||
void setInt(char **buf, const char *section, const char *key, int value); /* 设置整数 */
|
||||
int saveFile(const char *buf, const char *fileName); /* 写入文件 */
|
||||
|
||||
#ifdef __cplusplus
|
||||
};
|
||||
#endif
|
||||
|
||||
#endif
|
331
MentoHUST-OpenWrt-ipk/src/mystate.c
Normal file
331
MentoHUST-OpenWrt-ipk/src/mystate.c
Normal file
@ -0,0 +1,331 @@
|
||||
/* -*- Mode: C; tab-width: 4; -*- */
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:mystate.c
|
||||
* 摘 要:改变认证状态
|
||||
* 作 者:HustMoon@BYHH
|
||||
* 邮 箱:www.ehust@gmail.com
|
||||
*/
|
||||
#include "mystate.h"
|
||||
#include "myfunc.h"
|
||||
#include "dlfunc.h"
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#define MAX_SEND_COUNT 3 /* 最大超时次数 */
|
||||
|
||||
volatile int state = ID_DISCONNECT; /* 认证状态 */
|
||||
const u_char *capBuf = NULL; /* 抓到的包 */
|
||||
static u_char sendPacket[0x3E8]; /* 用来发送的包 */
|
||||
static int sendCount = 0; /* 同一阶段发包计数 */
|
||||
|
||||
extern const u_char STANDARD_ADDR[];
|
||||
extern char userName[];
|
||||
extern unsigned startMode;
|
||||
extern unsigned dhcpMode;
|
||||
extern u_char localMAC[], destMAC[];
|
||||
extern unsigned timeout;
|
||||
extern unsigned echoInterval;
|
||||
extern unsigned restartWait;
|
||||
extern char dhcpScript[];
|
||||
extern pcap_t *hPcap;
|
||||
extern u_char *fillBuf;
|
||||
extern unsigned fillSize;
|
||||
extern u_int32_t pingHost;
|
||||
#ifndef NO_ARP
|
||||
extern u_int32_t rip, gateway;
|
||||
extern u_char gateMAC[];
|
||||
static void sendArpPacket(); /* ARP监视 */
|
||||
#endif
|
||||
|
||||
static void setTimer(unsigned interval); /* 设置定时器 */
|
||||
static int renewIP(); /* 更新IP */
|
||||
static void fillEtherAddr(u_int32_t protocol); /* 填充MAC地址和协议 */
|
||||
static int sendStartPacket(); /* 发送Start包 */
|
||||
static int sendIdentityPacket(); /* 发送Identity包 */
|
||||
static int sendChallengePacket(); /* 发送Md5 Challenge包 */
|
||||
static int sendEchoPacket(); /* 发送心跳包 */
|
||||
static int sendLogoffPacket(); /* 发送退出包 */
|
||||
static int waitEchoPacket(); /* 等候响应包 */
|
||||
|
||||
static void setTimer(unsigned interval) /* 设置定时器 */
|
||||
{
|
||||
struct itimerval timer;
|
||||
timer.it_value.tv_sec = interval;
|
||||
timer.it_value.tv_usec = 0;
|
||||
timer.it_interval.tv_sec = interval;
|
||||
timer.it_interval.tv_usec = 0;
|
||||
setitimer(ITIMER_REAL, &timer, NULL);
|
||||
}
|
||||
|
||||
int switchState(int type)
|
||||
{
|
||||
if (state == type) /* 跟上次是同一状态? */
|
||||
sendCount++;
|
||||
else
|
||||
{
|
||||
state = type;
|
||||
sendCount = 0;
|
||||
}
|
||||
if (sendCount>=MAX_SEND_COUNT && type!=ID_ECHO) /* 超时太多次? */
|
||||
{
|
||||
switch (type)
|
||||
{
|
||||
case ID_START:
|
||||
printf(">> 找不到服务器,重启认证!\n");
|
||||
break;
|
||||
case ID_IDENTITY:
|
||||
printf(">> 发送用户名超时,重启认证!\n");
|
||||
break;
|
||||
case ID_CHALLENGE:
|
||||
printf(">> 发送密码超时,重启认证!\n");
|
||||
break;
|
||||
case ID_WAITECHO:
|
||||
printf(">> 等候响应包超时,自行响应!\n");
|
||||
return switchState(ID_ECHO);
|
||||
}
|
||||
return restart();
|
||||
}
|
||||
switch (type)
|
||||
{
|
||||
case ID_DHCP:
|
||||
return renewIP();
|
||||
case ID_START:
|
||||
return sendStartPacket();
|
||||
case ID_IDENTITY:
|
||||
return sendIdentityPacket();
|
||||
case ID_CHALLENGE:
|
||||
return sendChallengePacket();
|
||||
case ID_WAITECHO: /* 塞尔的就不ping了,不好计时 */
|
||||
return waitEchoPacket();
|
||||
case ID_ECHO:
|
||||
if (pingHost && sendCount*echoInterval > 60) { /* 1分钟左右 */
|
||||
if (isOnline() == -1) {
|
||||
printf(">> 认证掉线,开始重连!\n");
|
||||
return switchState(ID_START);
|
||||
}
|
||||
sendCount = 1;
|
||||
}
|
||||
#ifndef NO_ARP
|
||||
if (gateMAC[0] != 0xFE)
|
||||
sendArpPacket();
|
||||
#endif
|
||||
return sendEchoPacket();
|
||||
case ID_DISCONNECT:
|
||||
return sendLogoffPacket();
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int restart()
|
||||
{
|
||||
if (startMode >= 3) /* 标记服务器地址为未获取 */
|
||||
startMode -= 3;
|
||||
state = ID_START;
|
||||
sendCount = -1;
|
||||
setTimer(restartWait); /* restartWait秒后或者服务器请求后重启认证 */
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int renewIP()
|
||||
{
|
||||
setTimer(0); /* 取消定时器 */
|
||||
printf(">> 正在获取IP...\n");
|
||||
system(dhcpScript);
|
||||
printf(">> 操作结束。\n");
|
||||
dhcpMode += 3; /* 标记为已获取,123变为456,5不需再认证*/
|
||||
if (fillHeader() == -1)
|
||||
exit(EXIT_FAILURE);
|
||||
if (dhcpMode == 5)
|
||||
return switchState(ID_ECHO);
|
||||
return switchState(ID_START);
|
||||
}
|
||||
|
||||
static void fillEtherAddr(u_int32_t protocol)
|
||||
{
|
||||
memset(sendPacket, 0, 0x3E8);
|
||||
memcpy(sendPacket, destMAC, 6);
|
||||
memcpy(sendPacket+0x06, localMAC, 6);
|
||||
*(u_int32_t *)(sendPacket+0x0C) = htonl(protocol);
|
||||
}
|
||||
|
||||
static int sendStartPacket()
|
||||
{
|
||||
if (startMode%3 == 2) /* 赛尔 */
|
||||
{
|
||||
if (sendCount == 0)
|
||||
{
|
||||
printf(">> 寻找服务器...\n");
|
||||
memcpy(sendPacket, STANDARD_ADDR, 6);
|
||||
memcpy(sendPacket+0x06, localMAC, 6);
|
||||
*(u_int32_t *)(sendPacket+0x0C) = htonl(0x888E0101);
|
||||
*(u_int16_t *)(sendPacket+0x10) = 0;
|
||||
memset(sendPacket+0x12, 0xa5, 42);
|
||||
setTimer(timeout);
|
||||
}
|
||||
return pcap_sendpacket(hPcap, sendPacket, 60);
|
||||
}
|
||||
if (sendCount == 0)
|
||||
{
|
||||
printf(">> 寻找服务器...\n");
|
||||
fillStartPacket();
|
||||
fillEtherAddr(0x888E0101);
|
||||
memcpy(sendPacket+0x12, fillBuf, fillSize);
|
||||
setTimer(timeout);
|
||||
}
|
||||
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
|
||||
}
|
||||
|
||||
static int sendIdentityPacket()
|
||||
{
|
||||
int nameLen = strlen(userName);
|
||||
if (startMode%3 == 2) /* 赛尔 */
|
||||
{
|
||||
if (sendCount == 0)
|
||||
{
|
||||
printf(">> 发送用户名...\n");
|
||||
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0100);
|
||||
*(u_int16_t *)(sendPacket+0x10) = *(u_int16_t *)(sendPacket+0x14) = htons(nameLen+30);
|
||||
sendPacket[0x12] = 0x02;
|
||||
sendPacket[0x16] = 0x01;
|
||||
sendPacket[0x17] = 0x01;
|
||||
fillCernetAddr(sendPacket);
|
||||
memcpy(sendPacket+0x28, "03.02.05", 8);
|
||||
memcpy(sendPacket+0x30, userName, nameLen);
|
||||
setTimer(timeout);
|
||||
}
|
||||
sendPacket[0x13] = capBuf[0x13];
|
||||
return pcap_sendpacket(hPcap, sendPacket, nameLen+48);
|
||||
}
|
||||
if (sendCount == 0)
|
||||
{
|
||||
printf(">> 发送用户名...\n");
|
||||
fillEtherAddr(0x888E0100);
|
||||
nameLen = strlen(userName);
|
||||
*(u_int16_t *)(sendPacket+0x14) = *(u_int16_t *)(sendPacket+0x10) = htons(nameLen+5);
|
||||
sendPacket[0x12] = 0x02;
|
||||
sendPacket[0x13] = capBuf[0x13];
|
||||
sendPacket[0x16] = 0x01;
|
||||
memcpy(sendPacket+0x17, userName, nameLen);
|
||||
memcpy(sendPacket+0x17+nameLen, fillBuf, fillSize);
|
||||
setTimer(timeout);
|
||||
}
|
||||
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
|
||||
}
|
||||
|
||||
static int sendChallengePacket()
|
||||
{
|
||||
int nameLen = strlen(userName);
|
||||
if (startMode%3 == 2) /* 赛尔 */
|
||||
{
|
||||
if (sendCount == 0)
|
||||
{
|
||||
printf(">> 发送密码...\n");
|
||||
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0100);
|
||||
*(u_int16_t *)(sendPacket+0x10) = *(u_int16_t *)(sendPacket+0x14) = htons(nameLen+22);
|
||||
sendPacket[0x12] = 0x02;
|
||||
sendPacket[0x13] = capBuf[0x13];
|
||||
sendPacket[0x16] = 0x04;
|
||||
sendPacket[0x17] = 16;
|
||||
memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
|
||||
memcpy(sendPacket+0x28, userName, nameLen);
|
||||
setTimer(timeout);
|
||||
}
|
||||
return pcap_sendpacket(hPcap, sendPacket, nameLen+40);
|
||||
}
|
||||
if (sendCount == 0)
|
||||
{
|
||||
printf(">> 发送密码...\n");
|
||||
fillMd5Packet(capBuf+0x18);
|
||||
fillEtherAddr(0x888E0100);
|
||||
*(u_int16_t *)(sendPacket+0x14) = *(u_int16_t *)(sendPacket+0x10) = htons(nameLen+22);
|
||||
sendPacket[0x12] = 0x02;
|
||||
sendPacket[0x13] = capBuf[0x13];
|
||||
sendPacket[0x16] = 0x04;
|
||||
sendPacket[0x17] = 16;
|
||||
memcpy(sendPacket+0x18, checkPass(capBuf[0x13], capBuf+0x18, capBuf[0x17]), 16);
|
||||
memcpy(sendPacket+0x28, userName, nameLen);
|
||||
memcpy(sendPacket+0x28+nameLen, fillBuf, fillSize);
|
||||
setTimer(timeout);
|
||||
}
|
||||
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
|
||||
}
|
||||
|
||||
static int sendEchoPacket()
|
||||
{
|
||||
if (startMode%3 == 2) /* 赛尔 */
|
||||
{
|
||||
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0106);
|
||||
*(u_int16_t *)(sendPacket+0x10) = 0;
|
||||
memset(sendPacket+0x12, 0xa5, 42);
|
||||
switchState(ID_WAITECHO); /* 继续等待 */
|
||||
return pcap_sendpacket(hPcap, sendPacket, 60);
|
||||
}
|
||||
if (sendCount == 0)
|
||||
{
|
||||
u_char echo[] =
|
||||
{
|
||||
0x00,0x1E,0xFF,0xFF,0x37,0x77,0x7F,0x9F,0xFF,0xFF,0xD9,0x13,0xFF,0xFF,0x37,0x77,
|
||||
0x7F,0x9F,0xFF,0xFF,0xF7,0x2B,0xFF,0xFF,0x37,0x77,0x7F,0x3F,0xFF
|
||||
};
|
||||
printf(">> 发送心跳包以保持在线...\n");
|
||||
fillEtherAddr(0x888E01BF);
|
||||
memcpy(sendPacket+0x10, echo, sizeof(echo));
|
||||
setTimer(echoInterval);
|
||||
}
|
||||
fillEchoPacket(sendPacket);
|
||||
return pcap_sendpacket(hPcap, sendPacket, 0x2D);
|
||||
}
|
||||
|
||||
static int sendLogoffPacket()
|
||||
{
|
||||
setTimer(0); /* 取消定时器 */
|
||||
if (startMode%3 == 2) /* 赛尔 */
|
||||
{
|
||||
*(u_int16_t *)(sendPacket+0x0E) = htons(0x0102);
|
||||
*(u_int16_t *)(sendPacket+0x10) = 0;
|
||||
memset(sendPacket+0x12, 0xa5, 42);
|
||||
return pcap_sendpacket(hPcap, sendPacket, 60);
|
||||
}
|
||||
fillStartPacket(); /* 锐捷的退出包与Start包类似,不过其实不这样也是没问题的 */
|
||||
fillEtherAddr(0x888E0102);
|
||||
memcpy(sendPacket+0x12, fillBuf, fillSize);
|
||||
return pcap_sendpacket(hPcap, sendPacket, 0x3E8);
|
||||
}
|
||||
|
||||
static int waitEchoPacket()
|
||||
{
|
||||
if (sendCount == 0)
|
||||
setTimer(echoInterval);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifndef NO_ARP
|
||||
static void sendArpPacket()
|
||||
{
|
||||
u_char arpPacket[0x3C] = {
|
||||
0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x06,0x00,0x01,
|
||||
0x08,0x00,0x06,0x04,0x00};
|
||||
|
||||
if (gateMAC[0] != 0xFF) {
|
||||
memcpy(arpPacket, gateMAC, 6);
|
||||
memcpy(arpPacket+0x06, localMAC, 6);
|
||||
arpPacket[0x15]=0x02;
|
||||
memcpy(arpPacket+0x16, localMAC, 6);
|
||||
memcpy(arpPacket+0x1c, &rip, 4);
|
||||
memcpy(arpPacket+0x20, gateMAC, 6);
|
||||
memcpy(arpPacket+0x26, &gateway, 4);
|
||||
pcap_sendpacket(hPcap, arpPacket, 0x3C);
|
||||
}
|
||||
memset(arpPacket, 0xFF, 6);
|
||||
memcpy(arpPacket+0x06, localMAC, 6);
|
||||
arpPacket[0x15]=0x01;
|
||||
memcpy(arpPacket+0x16, localMAC, 6);
|
||||
memcpy(arpPacket+0x1c, &rip, 4);
|
||||
memset(arpPacket+0x20, 0, 6);
|
||||
memcpy(arpPacket+0x26, &gateway, 4);
|
||||
pcap_sendpacket(hPcap, arpPacket, 0x2A);
|
||||
}
|
||||
#endif
|
22
MentoHUST-OpenWrt-ipk/src/mystate.h
Normal file
22
MentoHUST-OpenWrt-ipk/src/mystate.h
Normal file
@ -0,0 +1,22 @@
|
||||
/*
|
||||
* Copyright (C) 2009, HustMoon Studio
|
||||
*
|
||||
* 文件名称:mystate.h
|
||||
* 摘 要:改变认证状态
|
||||
* 作 者:HustMoon@BYHH
|
||||
*/
|
||||
#ifndef HUSTMOON_MYSTATE_H
|
||||
#define HUSTMOON_MYSTATE_H
|
||||
|
||||
#define ID_DISCONNECT 0 /* 断开状态 */
|
||||
#define ID_START 1 /* 寻找服务器 */
|
||||
#define ID_IDENTITY 2 /* 发送用户名 */
|
||||
#define ID_CHALLENGE 3 /* 发送密码 */
|
||||
#define ID_ECHO 4 /* 发送心跳包 */
|
||||
#define ID_DHCP 5 /* 更新IP */
|
||||
#define ID_WAITECHO 6 /* 等待心跳包 */
|
||||
|
||||
int switchState(int type); /* 改变状态 */
|
||||
int restart(); /* 重启认证 */
|
||||
|
||||
#endif
|
16708
MentoHUST-OpenWrt-ipk/src/strnormalize.c
Normal file
16708
MentoHUST-OpenWrt-ipk/src/strnormalize.c
Normal file
File diff suppressed because it is too large
Load Diff
36
MentoHUST-OpenWrt-ipk/src/strnormalize.h
Normal file
36
MentoHUST-OpenWrt-ipk/src/strnormalize.h
Normal file
@ -0,0 +1,36 @@
|
||||
/**
|
||||
* Copyright(c) 2012-2013, All Rights Reserved.
|
||||
*
|
||||
* @file strnormalize.h
|
||||
* @details Check GBK character you could do
|
||||
* code >= 0x8000 && _pGbk2Utf16[code - 0x8000] != 0
|
||||
* @author cnangel
|
||||
* @version 1.0.0
|
||||
* @date 2012/10/09 11:44:58
|
||||
*/
|
||||
|
||||
#ifndef __STRNORMALIZE_H__
|
||||
#define __STRNORMALIZE_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define SNO_TO_LOWER 1
|
||||
#define SNO_TO_UPPER 2
|
||||
#define SNO_TO_HALF 4
|
||||
#define SNO_TO_SIMPLIFIED 8
|
||||
|
||||
void str_normalize_init();
|
||||
void str_normalize_gbk(char *text, unsigned options);
|
||||
void str_normalize_utf8(char *text, unsigned options);
|
||||
|
||||
int gbk_to_utf8(const char *from, unsigned int from_len, char **to, unsigned int *to_len);
|
||||
int utf8_to_gbk(const char *from, unsigned int from_len, char **to, unsigned int *to_len);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __STRNORMALIZE_H__ */
|
||||
|
10
MentoHUST-OpenWrt-ipk/src/types.h
Normal file
10
MentoHUST-OpenWrt-ipk/src/types.h
Normal file
@ -0,0 +1,10 @@
|
||||
#ifndef TYPES_H
|
||||
#define TYPES_H
|
||||
typedef unsigned char *POINTER;
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned char UCHAR;
|
||||
typedef unsigned short int WORD;
|
||||
typedef int LONG;
|
||||
typedef unsigned int DWORD;
|
||||
typedef unsigned int UINT4;
|
||||
#endif
|
85
gost/Makefile
Normal file
85
gost/Makefile
Normal file
@ -0,0 +1,85 @@
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt
|
||||
# <https://immortalwrt.org>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gost
|
||||
PKG_VERSION:=2.11.1
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/ginuerzh/gost/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILE:=LICENSE
|
||||
PKG_MAINTAINER:=CN_SZTL <cnsztl@immortalwrt.org>
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_GOST_COMPRESS_GOPROXY \
|
||||
CONFIG_GOST_COMPRESS_UPX
|
||||
|
||||
PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
GO_PKG:=github.com/ginuerzh/gost
|
||||
GO_PKG_BUILD_PKG:=github.com/ginuerzh/gost/cmd/gost
|
||||
GO_PKG_LDFLAGS:=-s -w
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
|
||||
|
||||
define Package/gost
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=GO Simple Tunnel
|
||||
URL:=https://github.com/ginuerzh/gost
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS)
|
||||
endef
|
||||
|
||||
define Package/gost/description
|
||||
A simple security tunnel written in Golang
|
||||
endef
|
||||
|
||||
define Package/gost/config
|
||||
config GOST_COMPRESS_GOPROXY
|
||||
bool "Compiling with GOPROXY proxy"
|
||||
default n
|
||||
|
||||
config GOST_COMPRESS_UPX
|
||||
bool "Compress executable files with UPX"
|
||||
default y
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_GOST_COMPRESS_GOPROXY),y)
|
||||
export GO111MODULE=on
|
||||
export GOPROXY=https://goproxy.io
|
||||
endif
|
||||
|
||||
define Build/Compile
|
||||
$(call GoPackage/Build/Compile)
|
||||
ifeq ($(CONFIG_GOST_COMPRESS_UPX),y)
|
||||
$(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/gost
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/gost/install
|
||||
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gost $(1)/usr/bin/gost
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(CURDIR)/files/gost.config $(1)/etc/config/gost
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(CURDIR)/files/gost.init $(1)/etc/init.d/gost
|
||||
endef
|
||||
|
||||
$(eval $(call GoBinPackage,gost))
|
||||
$(eval $(call BuildPackage,gost))
|
5
gost/files/gost.config
Normal file
5
gost/files/gost.config
Normal file
@ -0,0 +1,5 @@
|
||||
|
||||
config gost
|
||||
option enable '0'
|
||||
option run_command ''
|
||||
|
22
gost/files/gost.init
Executable file
22
gost/files/gost.init
Executable file
@ -0,0 +1,22 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Created By ImmortalWrt
|
||||
# https://github.com/project-openwrt
|
||||
|
||||
START=90
|
||||
STOP=10
|
||||
|
||||
enable="$(uci get gost.@gost[0].enable)"
|
||||
run_command="$(uci get gost.@gost[0].run_command)"
|
||||
|
||||
start()
|
||||
{
|
||||
stop
|
||||
|
||||
[ "${enable}" -ne "1" ] && exit 0
|
||||
/usr/bin/gost ${run_command} &
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
killall -9 "gost" > "/dev/null" 2>&1
|
||||
}
|
83
gowebdav/Makefile
Normal file
83
gowebdav/Makefile
Normal file
@ -0,0 +1,83 @@
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt
|
||||
# <https://immortalwrt.org>
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=gowebdav
|
||||
PKG_VERSION:=0.0.2
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/1715173329/gowebdav/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=0a6a2af4f24905ffea247b6044d01129d938af4b3a256bf19b42c52bb452f947
|
||||
|
||||
PKG_MAINTAINER:=CN_SZTL <cnsztl@immortalwrt.org>
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_GOWEBDAV_COMPRESS_GOPROXY \
|
||||
CONFIG_GOWEBDAV_COMPRESS_UPX
|
||||
|
||||
PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
GO_PKG:=github.com/1715173329/gowebdav
|
||||
GO_PKG_LDFLAGS:=-s -w
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(TOPDIR)/feeds/packages/lang/golang/golang-package.mk
|
||||
|
||||
define Package/gowebdav
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=File Transfer
|
||||
TITLE:=A simple WebDav server written in Golang.
|
||||
URL:=https://github.com/1715173329/gowebdav
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS)
|
||||
endef
|
||||
|
||||
define Package/gowebdav/description
|
||||
A simple WebDav server written in Golang.
|
||||
endef
|
||||
|
||||
define Package/gowebdav/config
|
||||
config GOWEBDAV_COMPRESS_GOPROXY
|
||||
bool "Compiling with GOPROXY proxy"
|
||||
default n
|
||||
|
||||
config GOWEBDAV_COMPRESS_UPX
|
||||
bool "Compress executable files with UPX"
|
||||
default y
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_GOWEBDAV_COMPRESS_GOPROXY),y)
|
||||
export GO111MODULE=on
|
||||
export GOPROXY=https://goproxy.io
|
||||
endif
|
||||
|
||||
define Build/Compile
|
||||
$(call GoPackage/Build/Compile)
|
||||
ifeq ($(CONFIG_GOWEBDAV_COMPRESS_UPX),y)
|
||||
$(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/gowebdav
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/gowebdav/install
|
||||
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/gowebdav $(1)/usr/bin/gowebdav
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) $(CURDIR)/files/gowebdav.config $(1)/etc/config/gowebdav
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) $(CURDIR)/files/gowebdav.init $(1)/etc/init.d/gowebdav
|
||||
endef
|
||||
|
||||
$(eval $(call GoBinPackage,gowebdav))
|
||||
$(eval $(call BuildPackage,gowebdav))
|
12
gowebdav/files/gowebdav.config
Normal file
12
gowebdav/files/gowebdav.config
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
config gowebdav 'config'
|
||||
option enable '0'
|
||||
option listen_port '6086'
|
||||
option username 'user'
|
||||
option password 'pass'
|
||||
option root_dir '/mnt'
|
||||
option read_only '0'
|
||||
option allow_wan '0'
|
||||
option use_https '0'
|
||||
option cert_cer ''
|
||||
option cert_key ''
|
56
gowebdav/files/gowebdav.init
Executable file
56
gowebdav/files/gowebdav.init
Executable file
@ -0,0 +1,56 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2021 ImmortalWrt
|
||||
|
||||
START=99
|
||||
STOP=10
|
||||
|
||||
init_conf() {
|
||||
config_load "gowebdav"
|
||||
config_get "enable" "config" "enable" "0"
|
||||
config_get "listen_port" "config" "listen_port" "6086"
|
||||
config_get "username" "config" "username"
|
||||
config_get "password" "config" "password"
|
||||
config_get "root_dir" "config" "root_dir" "/mnt"
|
||||
config_get "read_only" "config" "read_only" "0"
|
||||
config_get "allow_wan" "config" "allow_wan" "0"
|
||||
config_get "use_https" "config" "use_https" "0"
|
||||
config_get "cert_cer" "config" "cert_cer"
|
||||
config_get "cert_key" "config" "cert_key"
|
||||
|
||||
config_load "network"
|
||||
config_get "lan_addr" "lan" "ipaddr" "192.168.1.1"
|
||||
}
|
||||
|
||||
set_firewall() {
|
||||
if [ "${set_type}" = "start" ]; then
|
||||
mkdir -p "/var/etc/"
|
||||
iptables -I INPUT -p tcp --dport "${listen_port}" -j ACCEPT
|
||||
echo "iptables -I INPUT -p tcp --dport "${listen_port}" -j ACCEPT" > "/var/etc/gowebdav.include"
|
||||
elif [ "${set_type}" = "stop" ]; then
|
||||
iptables -D INPUT -p tcp --dport "${listen_port}" -j ACCEPT
|
||||
echo "" > "/var/etc/gowebdav.include"
|
||||
fi
|
||||
}
|
||||
|
||||
start() {
|
||||
init_conf
|
||||
|
||||
stop
|
||||
|
||||
[ "${enable}" -ne "1" ] && exit 0
|
||||
|
||||
mkdir -p "${root_dir}"
|
||||
|
||||
[ "${allow_wan}" -ne "1" ] && listen_addr="${lan_addr}" || { listen_addr="0.0.0.0"; set_type="start" && set_firewall 2>"/dev/null"; }
|
||||
{ [ -n "${username}" ] && [ -n "${password}" ]; } && auth_arg="-user ${username} -password ${password}"
|
||||
[ "${read_only}" -eq "1" ] && readonly_arg="-read-only"
|
||||
{ [ "${use_https}" -eq "1" ] && [ -e "${cert_cer}" ] && [ -e "${cert_key}" ]; } && https_arg="-https-mode -https-cert-file ${cert_cer} -https-key-file ${cert_key}"
|
||||
/usr/bin/gowebdav -dir "${root_dir}" -http "${listen_addr}:${listen_port}" ${auth_arg} ${readonly_arg} ${https_arg} &
|
||||
}
|
||||
|
||||
stop() {
|
||||
init_conf
|
||||
|
||||
set_type="stop" && set_firewall 2>"/dev/null"
|
||||
killall "gowebdav" 2>"/dev/null"
|
||||
}
|
50
iptvhelper/Makefile
Normal file
50
iptvhelper/Makefile
Normal file
@ -0,0 +1,50 @@
|
||||
# Copyright 2019 Shun Li <riverscn@gmail.com>
|
||||
# Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=iptvhelper
|
||||
PKG_VERSION:=0.1.1
|
||||
PKG_RELEASE:=1
|
||||
PKG_MAINTAINER:=Shun Li <riverscn@gmail.com>
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/iptvhelper
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=Routing and Redirection
|
||||
DEPENDS:= \
|
||||
+ipset \
|
||||
+iptables
|
||||
TITLE:=Scripts for configure IPTV easily
|
||||
MAINTAINER:=Shun Li <riverscn@gmail.com>
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/iptvhelper/description
|
||||
Scripts for configure IPTV easily
|
||||
endef
|
||||
|
||||
define Package/iptvhelper/conffiles
|
||||
/etc/config/iptvhelper
|
||||
/etc/firewall.iptvhelper
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/iptvhelper/postinst
|
||||
#!/bin/sh
|
||||
endef
|
||||
|
||||
define Package/iptvhelper/postrm
|
||||
#!/bin/sh
|
||||
endef
|
||||
|
||||
define Package/iptvhelper/install
|
||||
$(CP) ./files/* $(1)
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,iptvhelper))
|
8
iptvhelper/files/etc/config/iptvhelper
Normal file
8
iptvhelper/files/etc/config/iptvhelper
Normal file
@ -0,0 +1,8 @@
|
||||
config tvbox 'default'
|
||||
option disabled '1'
|
||||
option respawn '1'
|
||||
option mac '00:00:00:00:00:00'
|
||||
option ipset '1'
|
||||
option dns_redir '1'
|
||||
|
||||
|
2
iptvhelper/files/etc/firewall.iptvhelper
Normal file
2
iptvhelper/files/etc/firewall.iptvhelper
Normal file
@ -0,0 +1,2 @@
|
||||
#!/bin/sh
|
||||
test -s "/etc/init.d/iptvhelper" && /etc/init.d/iptvhelper reload
|
127
iptvhelper/files/etc/init.d/iptvhelper
Executable file
127
iptvhelper/files/etc/init.d/iptvhelper
Executable file
@ -0,0 +1,127 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright 2019 Shun Li <riverscn@gmail.com>
|
||||
# Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
START=95
|
||||
USE_PROCD=1
|
||||
|
||||
_ipt() {
|
||||
cmd="$(echo "$@" | sed 's|-A|-D|g;s|-I|-D|g')"
|
||||
while iptables $cmd &>/dev/null; do
|
||||
:
|
||||
done
|
||||
iptables $@
|
||||
}
|
||||
|
||||
destroy_iptv_ipset() {
|
||||
for ip_set in $(ipset list | awk '/iptvhelper/ {print $2}'); do ipset destroy $ip_set; done
|
||||
}
|
||||
|
||||
clear_iptv_rules() {
|
||||
iptables-save --counters | grep -v "iptvhelper-rule" | iptables-restore --counters
|
||||
}
|
||||
|
||||
append_arg() {
|
||||
local cfg="$1"
|
||||
local var="$2"
|
||||
local opt="$3"
|
||||
local def="$4"
|
||||
local val
|
||||
|
||||
config_get val "$cfg" "$var"
|
||||
[ -n "$val" -o -n "$def" ] && procd_append_param command $opt "${val:-$def}"
|
||||
}
|
||||
|
||||
append_bool() {
|
||||
local cfg="$1"
|
||||
local var="$2"
|
||||
local opt="$3"
|
||||
local def="$4"
|
||||
local val
|
||||
|
||||
config_get_bool val "$cfg" "$var" "$def"
|
||||
[ "$val" = 1 ] && procd_append_param command "$opt"
|
||||
}
|
||||
|
||||
start_instance() {
|
||||
local cfg="$1"
|
||||
local aux
|
||||
|
||||
config_get_bool aux "$cfg" 'disabled' '0'
|
||||
[ "$aux" = 1 ] && return 1
|
||||
|
||||
logger "iptvhelper.$cfg: instance starting"
|
||||
|
||||
local IPTV_MAC
|
||||
local IPTV_DNS_REDIR
|
||||
local IPTV_IPSET
|
||||
|
||||
config_get IPTV_MAC $cfg mac
|
||||
config_get IPTV_DNS_REDIR $cfg dns_redir
|
||||
config_get IPTV_IPSET $cfg ipset
|
||||
logger "iptvhelper.$cfg: topbox mac=$IPTV_MAC"
|
||||
|
||||
if [[ $IPTV_DNS_REDIR == '1' ]]; then
|
||||
logger "iptvhelper.$cfg: topbox DNS redierct enabled"
|
||||
_ipt -t nat -A PREROUTING -m mac --mac-source $IPTV_MAC -m comment --comment "iptvhelper-rule" -p udp --dport 53 -j REDIRECT --to-ports 53
|
||||
fi
|
||||
|
||||
if [[ $IPTV_IPSET='1' ]]; then
|
||||
logger "iptvhelper.$cfg: topbox ipset enabled"
|
||||
if ! ipset -q list iptvhelper_$cfg >/dev/null; then
|
||||
ipset create iptvhelper_$cfg nethash
|
||||
fi
|
||||
_ipt -t nat -I PREROUTING -m mac --mac-source $IPTV_MAC -m comment --comment "iptvhelper-rule" -m set ! --match-set iptvhelper_$cfg dst -m conntrack --ctstate NEW -j LOG --log-prefix "iptvhelper.$cfg:"
|
||||
procd_open_instance
|
||||
procd_set_param command /usr/sbin/iptvhelper.sh $cfg
|
||||
config_get_bool aux "$cfg" 'respawn' '0'
|
||||
[ "$aux" = 1 ] && procd_set_param respawn
|
||||
procd_set_param pidfile /var/run/iptvhelper_$cfg.pid
|
||||
procd_close_instance
|
||||
fi
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "iptvhelper"
|
||||
}
|
||||
|
||||
start_service() {
|
||||
logger "iptvhelper: starting"
|
||||
echo "iptvhelper: starting"
|
||||
config_load iptvhelper
|
||||
config_foreach start_instance tvbox
|
||||
if uci -q show firewall >/dev/null; then
|
||||
if ! uci -q get firewall.iptvhelper >/dev/null; then
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
set firewall.iptvhelper=include
|
||||
set firewall.iptvhelper.type='script'
|
||||
set firewall.iptvhelper.path='/etc/firewall.iptvhelper'
|
||||
set firewall.iptvhelper.family='any'
|
||||
set firewall.iptvhelper.reload='1'
|
||||
commit firewall
|
||||
EOF
|
||||
fi
|
||||
fi
|
||||
}
|
||||
|
||||
stop_service() {
|
||||
if uci -q show firewall >/dev/null; then
|
||||
if uci -q get firewall.iptvhelper >/dev/null; then
|
||||
uci delete firewall.iptvhelper
|
||||
uci commit firewall
|
||||
fi
|
||||
fi
|
||||
for pid in $(ps | grep -v awk | awk '/iptvhelper.sh/ {print $1}'); do kill -9 $pid; done
|
||||
for pid in $(ps | grep -v awk | awk '/logread -e iptvhelper/ {print $1}'); do kill -9 $pid; done
|
||||
clear_iptv_rules
|
||||
destroy_iptv_ipset
|
||||
logger "iptvhelper: stopped"
|
||||
echo "iptvhelper: stopped"
|
||||
}
|
||||
|
||||
reload_service() {
|
||||
logger "iptvhelper: reloading"
|
||||
echo "iptvhelper: reloading"
|
||||
stop
|
||||
start
|
||||
}
|
24
iptvhelper/files/usr/sbin/iptvhelper.sh
Executable file
24
iptvhelper/files/usr/sbin/iptvhelper.sh
Executable file
@ -0,0 +1,24 @@
|
||||
#!/bin/sh
|
||||
|
||||
# Copyright 2019 Shun Li <riverscn@gmail.com>
|
||||
# Licensed to the public under the GNU General Public License v3.
|
||||
|
||||
add_to_set() {
|
||||
local ip=$1
|
||||
local cfg=$2
|
||||
local subnet=$ip/24
|
||||
ping -W1 -c1 $ip &>/dev/null && return
|
||||
if ! ipset -q test iptvhelper_$cfg $subnet; then
|
||||
ipset add iptvhelper_$cfg $subnet
|
||||
echo added $subnet to set iptvhelper_$cfg
|
||||
fi
|
||||
}
|
||||
|
||||
echo $1
|
||||
|
||||
logread -e "iptvhelper\.$1" -f |
|
||||
while read line; do
|
||||
ip=$(echo "$line" | sed -r 's|.*DST=([0-9.]+).*|\1|')
|
||||
echo requested $ip
|
||||
add_to_set $ip $1 &
|
||||
done
|
674
luci-app-airwhu/LICENSE
Executable file
674
luci-app-airwhu/LICENSE
Executable file
@ -0,0 +1,674 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
{one line to give the program's name and a brief idea of what it does.}
|
||||
Copyright (C) {year} {name of author}
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
{project} Copyright (C) {year} {fullname}
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
<http://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<http://www.gnu.org/philosophy/why-not-lgpl.html>.
|
51
luci-app-airwhu/Makefile
Executable file
51
luci-app-airwhu/Makefile
Executable file
@ -0,0 +1,51 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-airwhu
|
||||
PKG_VERSION=1.0
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/luci-app-airwhu
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
DEPENDS:=+mentohust +kmod-ipt-nat6
|
||||
TITLE:=luci-app-airwhu
|
||||
PKGARCH:=all
|
||||
endef
|
||||
|
||||
define Package/luci-app-airwhu/description
|
||||
LuCI web-interface for Ruijie 802.1X Client with IPv6 NAT.
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
mkdir -p $(PKG_BUILD_DIR)
|
||||
$(CP) ./* $(PKG_BUILD_DIR)/
|
||||
po2lmo $(PKG_BUILD_DIR)/po/airwhu.zh_Hans.po $(PKG_BUILD_DIR)/po/airwhu.zh-cn.lmo
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/luci-app-airwhu/install
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/iface
|
||||
$(INSTALL_DIR) $(1)/bin
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/model/cbi
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/controller
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
|
||||
$(INSTALL_CONF) ./files/root/etc/config/airwhu $(1)/etc/config/airwhu
|
||||
$(INSTALL_BIN) ./files/root/etc/init.d/mentohust $(1)/etc/init.d/mentohust
|
||||
$(INSTALL_BIN) ./files/root/etc/hotplug.d/iface/99-ipv6nat $(1)/etc/hotplug.d/iface/99-ipv6nat
|
||||
$(INSTALL_BIN) ./files/root/bin/ipv6masq.sh $(1)/bin/ipv6masq.sh
|
||||
$(INSTALL_DATA) ./files/root/usr/lib/lua/luci/model/cbi/airwhu.lua $(1)/usr/lib/lua/luci/model/cbi/airwhu.lua
|
||||
$(INSTALL_DATA) ./files/root/usr/lib/lua/luci/controller/airwhu.lua $(1)/usr/lib/lua/luci/controller/airwhu.lua
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/po/airwhu.zh-cn.lmo $(1)/usr/lib/lua/luci/i18n/airwhu.zh-cn.lmo
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-airwhu))
|
23
luci-app-airwhu/README.md
Normal file
23
luci-app-airwhu/README.md
Normal file
@ -0,0 +1,23 @@
|
||||
## Compile
|
||||
|
||||
在OpenWrt SDK中的package目录下执行如下命令:
|
||||
|
||||
`$ git clone https://github.com/KyleRicardo/luci-app-airwhu.git`
|
||||
|
||||
在luci-app-airwhu/tools/po2lmo下打开终端,运行如下命令:
|
||||
|
||||
`$ make && sudo make install`
|
||||
|
||||
然后在OpenWrt SDK根目录下执行如下命令:
|
||||
|
||||
`$ make package/luci-app-airwhu/compile V=s`
|
||||
|
||||
编译成功后,找到生成的ipk文件拷贝到路由器中,用opkg安装就可以使用了。
|
||||
|
||||
## Install
|
||||
|
||||
代码中只包含Lua和Bash脚本,所以不受限于平台,编译后的文件可以在任何平台安装:
|
||||
|
||||
`$ opkg install luci-app-airwhu_1.0-1_all.ipk`
|
||||
|
||||
该luci界面依赖MentoHUST以及kmod-ipt-nat6这两个ipk包。
|
41
luci-app-airwhu/files/root/bin/ipv6masq.sh
Executable file
41
luci-app-airwhu/files/root/bin/ipv6masq.sh
Executable file
@ -0,0 +1,41 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#Author:KyleRicardo
|
||||
#Email:shaoyz714@126.com
|
||||
|
||||
action=$1
|
||||
|
||||
if [ "$action"x = "install"x ]; then
|
||||
uci delete network.globals.ula_prefix
|
||||
|
||||
uci set network.wan6.peerdns='0'
|
||||
uci set network.wan6.dns='2001:da8:202:10::36'
|
||||
|
||||
uci delete network.lan.ip6assign
|
||||
uci set network.lan.ip6addr='BABE:BABE:BABE:BABE::1/64'
|
||||
uci set network.lan.ip6prefix='BABE:BABE:BABE:BABE::/64'
|
||||
|
||||
uci set dhcp.lan.ra_management='1'
|
||||
uci set dhcp.lan.ra_default='1'
|
||||
|
||||
uci set $(uci show firewall|grep Allow-ICMPv6-Forward|sed -e 's/.name[^ ]*'//).enabled='0'
|
||||
|
||||
uci commit
|
||||
|
||||
|
||||
elif [ "$action"x = "uninstall"x ]; then
|
||||
uci set network.globals.ula_prefix='fdad:91b7:54bb::/48'
|
||||
|
||||
uci delete network.wan6.peerdns='0'
|
||||
uci delete network.wan6.dns='2001:da8:202:10::36'
|
||||
|
||||
uci set network.lan.ip6assign='60'
|
||||
uci delete network.lan.ip6addr='BABE:BABE:BABE:BABE::1/64'
|
||||
uci delete network.lan.ip6prefix='BABE:BABE:BABE:BABE::/64'
|
||||
|
||||
uci delete dhcp.lan.ra_management='1'
|
||||
uci delete dhcp.lan.ra_default='1'
|
||||
|
||||
uci delete $(uci show firewall|grep Allow-ICMPv6-Forward|sed -e 's/.name[^ ]*'//).enabled
|
||||
|
||||
uci commit
|
||||
fi
|
25
luci-app-airwhu/files/root/etc/config/airwhu
Executable file
25
luci-app-airwhu/files/root/etc/config/airwhu
Executable file
@ -0,0 +1,25 @@
|
||||
|
||||
config switch
|
||||
option enableauth
|
||||
option startwithboot
|
||||
option enableipv6
|
||||
config auth
|
||||
option Username
|
||||
option Password
|
||||
option ifname
|
||||
option IP
|
||||
option Mask
|
||||
option Gateway
|
||||
option DNS
|
||||
option PingHost
|
||||
option Timeout
|
||||
option EchoInterval
|
||||
option RestartWait
|
||||
option MaxFail
|
||||
option StartMode
|
||||
option DHCPMode
|
||||
option DaemonMode
|
||||
option ShowNotify
|
||||
option Version
|
||||
option DataFile
|
||||
option DHCPScript
|
56
luci-app-airwhu/files/root/etc/hotplug.d/iface/99-ipv6nat
Executable file
56
luci-app-airwhu/files/root/etc/hotplug.d/iface/99-ipv6nat
Executable file
@ -0,0 +1,56 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#Author:KyleRicardo
|
||||
#Email:shaoyz714@126.com
|
||||
|
||||
|
||||
[ "$ACTION" = ifup ] || exit 0
|
||||
iface=wan6
|
||||
[ -z "$iface" -o "$INTERFACE" = "$iface" ] || exit 0
|
||||
ip -6 route add `ip -6 route show default|sed -e 's/from [^ ]* //'`
|
||||
logger -t IPv6 "Add IPv6 default route."
|
||||
|
||||
MAX_TRIES=99
|
||||
|
||||
WAN6_NAME="wan6"
|
||||
|
||||
WAN6_INTERFACE=$(uci get "network.$WAN6_NAME.ifname")
|
||||
#eth0.2 by default
|
||||
|
||||
LAN_IP6PREFIX=$(uci get network.lan.ip6prefix)
|
||||
#e.g. aaaa:bbbb:cccc:dddd::/64
|
||||
|
||||
#LAN_ULA_PREFIX=$(uci get network.globals.ula_prefix)
|
||||
#e.g. ddc2:d512:65f5::/48
|
||||
|
||||
PROBE=0
|
||||
|
||||
COUNT=1
|
||||
|
||||
while [ $PROBE -eq 0 ]
|
||||
do
|
||||
if [ $COUNT -gt $MAX_TRIES ]
|
||||
then
|
||||
logger -t NAT6 "No IPv6 route found (reached retry limit $MAX_TRIES times)" && exit 1
|
||||
fi
|
||||
sleep 5
|
||||
logger -t NAT6 "Probing IPv6 route ($COUNT time)"
|
||||
COUNT=$((COUNT+1))
|
||||
PROBE=$(route -A inet6 | grep -c '::/0')
|
||||
done
|
||||
|
||||
#ip6tables -t nat -I POSTROUTING -s "$LAN_ULA_PREFIX" -o "$WAN6_INTERFACE" -j MASQUERADE
|
||||
ip6tables -t nat -I POSTROUTING -s "$LAN_IP6PREFIX" -o "$WAN6_INTERFACE" -j MASQUERADE
|
||||
|
||||
#WAN6_GATEWAY=$(route -A inet6 -e | grep "$WAN6_INTERFACE" | awk '/::\/0/{print $2; exit}')
|
||||
#get gateway from routing table. !!!Caution!!! May not work !
|
||||
WAN6_GATEWAY=$(ifconfig eth0.2 | grep 'Global' | awk '{print $3}'| awk -F':' '{print $1":"$2":"$3":"$4"::1"}')
|
||||
#caculate gateway from wan ipv6
|
||||
#WAN6_GATEWAY=$(tracepath6 -n tv.byr.cn | grep ' 1: ' | awk 'NR==1 {print $2}')
|
||||
#opkg install iputils-tracepath6 . change tv.byr.cn for faster site. e.g. ipv6.bjtu.edu.cn
|
||||
|
||||
#route -A inet6 add 2000::/3 gw "$WAN6_GATEWAY" dev "$WAN6_INTERFACE"
|
||||
route -A inet6 add default gw "$WAN6_GATEWAY" dev "$WAN6_INTERFACE"
|
||||
|
||||
logger -t NAT6 "Done with IPv6 settings"
|
||||
|
||||
|
49
luci-app-airwhu/files/root/etc/init.d/mentohust
Executable file
49
luci-app-airwhu/files/root/etc/init.d/mentohust
Executable file
@ -0,0 +1,49 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
#Author:KyleRicardo
|
||||
#Email:shaoyz714@126.com
|
||||
|
||||
START=65
|
||||
STOP=10
|
||||
|
||||
start()
|
||||
{
|
||||
if [ $(uci get airwhu.@switch[0].enableauth) ] ;
|
||||
then
|
||||
local Username=$(uci get airwhu.@auth[0].Username)
|
||||
local Password=$(uci get airwhu.@auth[0].Password)
|
||||
local ifname=$(uci get airwhu.@auth[0].ifname)
|
||||
local IP=$(uci get airwhu.@auth[0].IP)
|
||||
local Mask=$(uci get airwhu.@auth[0].Mask)
|
||||
local Gateway=$(uci get airwhu.@auth[0].Gateway)
|
||||
local DNS=$(uci get airwhu.@auth[0].DNS)
|
||||
local PingHost=$(uci get airwhu.@auth[0].PingHost)
|
||||
local Timeout=$(uci get airwhu.@auth[0].Timeout)
|
||||
local EchoInterval=$(uci get airwhu.@auth[0].EchoInterval)
|
||||
local RestartWait=$(uci get airwhu.@auth[0].RestartWait)
|
||||
local MaxFail=$(uci get airwhu.@auth[0].MaxFail)
|
||||
local StartMode=$(uci get airwhu.@auth[0].StartMode)
|
||||
local DHCPMode=$(uci get airwhu.@auth[0].DHCPMode)
|
||||
local DaemonMode=$(uci get airwhu.@auth[0].DaemonMode)
|
||||
local ShowNotify=$(uci get airwhu.@auth[0].ShowNotify)
|
||||
local Version=$(uci get airwhu.@auth[0].Version)
|
||||
local DataFile=$(uci get airwhu.@auth[0].DataFile)
|
||||
local DHCPScript=$(uci get airwhu.@auth[0].DHCPScript)
|
||||
mentohust -u$Username -p$Password -n$ifname -b$DaemonMode -a$StartMode -d$DaemonMode -c"$DHCPScript" -w>/dev/null 2>&1
|
||||
#Temporarily designed only for whu. To be continued...
|
||||
else
|
||||
stop
|
||||
fi
|
||||
|
||||
}
|
||||
|
||||
stop()
|
||||
{
|
||||
sync
|
||||
mentohust -k >/dev/null 2>&1
|
||||
}
|
||||
|
||||
restart()
|
||||
{
|
||||
stop
|
||||
start
|
||||
}
|
5
luci-app-airwhu/files/root/usr/lib/lua/luci/controller/airwhu.lua
Executable file
5
luci-app-airwhu/files/root/usr/lib/lua/luci/controller/airwhu.lua
Executable file
@ -0,0 +1,5 @@
|
||||
module("luci.controller.airwhu", package.seeall)
|
||||
|
||||
function index()
|
||||
entry({"admin", "services", "AirWHU"}, cbi("airwhu"), _("AirWHU"), 100)
|
||||
end
|
115
luci-app-airwhu/files/root/usr/lib/lua/luci/model/cbi/airwhu.lua
Normal file
115
luci-app-airwhu/files/root/usr/lib/lua/luci/model/cbi/airwhu.lua
Normal file
@ -0,0 +1,115 @@
|
||||
--[[
|
||||
|
||||
LuCI - Lua Configuration Interface
|
||||
LICENSE under GPLv3.
|
||||
Copyright 2017 KyleRicardo[W.B.L.E. TeAm] <shaoyz714@126.com>
|
||||
|
||||
]]
|
||||
--
|
||||
require("luci.sys")
|
||||
require("luci.tools.webadmin")
|
||||
|
||||
local IsOnAir = (luci.sys.call("pidof mentohust > /dev/null") == 0)
|
||||
if IsOnAir then
|
||||
state_msg = "<b><font color=\"green\">" .. translate("Running") .. "</font></b>"
|
||||
else
|
||||
state_msg = "<b><font color=\"red\">" .. translate("Not Running") .. "</font></b>"
|
||||
end
|
||||
|
||||
m = Map("airwhu", translate("AirWHU"), translate("Configure Ruijie 802.1X client with IPv6 NAT based on Masquerade.") .. "<br /><br />" .. translate("Status") .. " : " .. state_msg)
|
||||
|
||||
s = m:section(TypedSection, "switch", translate("Global Switch"), translate("Configure global 802.1X Authentication and IPv6-NAT on-off."))
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
s:option(Flag, "enableauth", translate("Enable 802.1X Auth"), translate("Enable or disable Ruijie 802.1X authentication."))
|
||||
tmp = s:option(Flag, "startwithboot", translate("Start with boot"), translate("Start Ruijie 802.1X Authentication based on MentoHUST when the router is booting."))
|
||||
tmp:depends("enableauth","1")
|
||||
s:option(Flag, "enableipv6", translate("Enable IPv6 NAT"), translate("Enable IPv6 NAT pass-through based on ip6tables MASQUERADE."))
|
||||
|
||||
s = m:section(TypedSection, "auth", translate("Config Authentication"), translate("The options below are all of MentoHUST's arguments."))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
ur = s:option(Value, "Username", translate("Username"))
|
||||
ur.rmempty = false
|
||||
|
||||
pw = s:option(Value, "Password", translate("Password"))
|
||||
pw.password = true
|
||||
pw.rmempty = false
|
||||
|
||||
wan_dev = luci.sys.exec("uci get network.wan.ifname")
|
||||
wan_dev = string.sub(wan_dev,1,string.len(wan_dev)-1)
|
||||
ifname = s:option(ListValue, "ifname", translate("Interfaces"))
|
||||
ifname:value(wan_dev)
|
||||
|
||||
s:option(Value, "IP", translate("IP"), translate("default to localhost's IP")).default = "0.0.0.0"
|
||||
|
||||
s:option(Value, "Mask", translate("Netmask"), translate("default to localhost's netmask")).default = "255.255.255.0"
|
||||
|
||||
s:option(Value, "Gateway", translate("Gateway"), translate("default to 0.0.0.0")).default = "0.0.0.0"
|
||||
|
||||
s:option(Value, "DNS", translate("DNS"), translate("default to 0.0.0.0")).default = "0.0.0.0"
|
||||
|
||||
s:option(Value, "PingHost", translate("Ping host"), translate("default to 0.0.0.0,i.e. disable this function")).default = "0.0.0.0"
|
||||
|
||||
s:option(Value, "Timeout", translate("Authenticate timeout(s)"), translate("default to 8s")).default = "8"
|
||||
|
||||
s:option(Value, "EchoInterval", translate("Heartbeat timeout(s)"), translate("default to 30s")).default = "30"
|
||||
|
||||
s:option(Value, "RestartWait", translate("Timeout on failure(s)"), translate("default to 15s")).default = "15"
|
||||
|
||||
s:option(Value, "MaxFail", translate("Max failure times"), translate("0 means no limit,default to 8")).default = "8"
|
||||
|
||||
t = s:option(ListValue, "StartMode", translate("mulcast address"), translate("default to 1"))
|
||||
t:value("0", translate("0(standard)"))
|
||||
t:value("1", translate("1(ruijjie)"))
|
||||
t:value("2", translate("2(saier)"))
|
||||
t.default = "1"
|
||||
|
||||
t = s:option(ListValue, "DHCPMode", translate("DHCP type"), translate("default to 1"))
|
||||
t:value("0", translate("0(not in used)"))
|
||||
t:value("1", translate("1(secondary authenticate)"))
|
||||
t:value("2", translate("2(post authenticate)"))
|
||||
t:value("3", translate("3(pre authenticate)"))
|
||||
t.default = "1"
|
||||
|
||||
t = s:option(ListValue, "DaemonMode", translate("run in daemon mode"), translate("default to 3"))
|
||||
t:value("0", translate("0(no)"))
|
||||
t:value("1", translate("1(yes,turn off output)"))
|
||||
t:value("2", translate("2(yes,persevere output)"))
|
||||
t:value("3", translate("3(yes,output to file)"))
|
||||
t.default = "3"
|
||||
|
||||
s:option(Value, "ShowNotify", translate("display notification"), translate("0(no),1-20(yes),default to 0")).default = "0"
|
||||
|
||||
s:option(Value, "Version", translate("client version"), translate("default to 0.00,compatible with xrgsu")).default = "0.00"
|
||||
|
||||
tmp = s:option(Value, "DataFile", translate("customized data file"), translate("not in used by default"))
|
||||
tmp.rmempty = true
|
||||
|
||||
script = s:option(Value, "DHCPScript", translate("DHCP script"), translate("use dhclient by default"))
|
||||
script.default = "udhcpc -i "..wan_dev
|
||||
|
||||
local apply = luci.http.formvalue("cbi.apply")
|
||||
if apply then
|
||||
if luci.sys.exec("uci get airwhu.@switch[0].enableauth") then
|
||||
luci.sys.exec("/etc/init.d/mentohust restart")
|
||||
else
|
||||
luci.sys.exec("/etc/init.d/mentohust stop")
|
||||
end
|
||||
|
||||
if luci.sys.exec("uci get airwhu.@switch[0].startwithboot") then
|
||||
luci.sys.exec("/etc/init.d/mentohust enable")
|
||||
else
|
||||
luci.sys.exec("/etc/init.d/mentohust disable")
|
||||
end
|
||||
|
||||
if luci.sys.exec("uci get airwhu.@switch[0].enableipv6") then
|
||||
luci.sys.exec("sh /bin/ipv6masq.sh install")
|
||||
else
|
||||
luci.sys.exec("sh /bin/ipv6masq.sh uninstall")
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
258
luci-app-airwhu/po/airwhu.zh_Hans.po
Normal file
258
luci-app-airwhu/po/airwhu.zh_Hans.po
Normal file
@ -0,0 +1,258 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: airwhu\n"
|
||||
"POT-Creation-Date: 2017-05-11 19:39+0800\n"
|
||||
"PO-Revision-Date: 2017-05-11 19:40+0800\n"
|
||||
"Last-Translator: KyleRicardo <shaoyz714@126.com>\n"
|
||||
"Language-Team: [W.B.L.E. TeAm] <shaoyz714@126.com>\n"
|
||||
"Language: en_US\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 1.8.8\n"
|
||||
"X-Poedit-Basepath: ../files\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"X-Poedit-SourceCharset: UTF-8\n"
|
||||
"X-Poedit-KeywordsList: translate\n"
|
||||
"X-Poedit-SearchPath-0: .\n"
|
||||
|
||||
#: root/usr/lib/lua/luci/controller/airwhu.lua:4
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:19
|
||||
msgid "AirWHU"
|
||||
msgstr "AirWHU"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:14
|
||||
msgid "Running"
|
||||
msgstr "运行中"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:16
|
||||
msgid "Not Running"
|
||||
msgstr "未运行"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:19
|
||||
msgid "Configure Ruijie 802.1X client with IPv6 NAT based on Masquerade."
|
||||
msgstr "配置基于IPv6 Masquerade技术的锐捷802.1X认证网络。"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:19
|
||||
msgid "Status"
|
||||
msgstr "状态"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:21
|
||||
msgid "Global Switch"
|
||||
msgstr "全局开关"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:21
|
||||
msgid "Configure global 802.1X Authentication and IPv6-NAT on-off."
|
||||
msgstr "配置全局802.1X认证与IPv6 NAT开关。"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:25
|
||||
msgid "Enable 802.1X Auth"
|
||||
msgstr "开启锐捷认证"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:25
|
||||
msgid "Enable or disable Ruijie 802.1X authentication."
|
||||
msgstr "打开或关闭锐捷802.1X认证。"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:26
|
||||
msgid "Start with boot"
|
||||
msgstr "开机启动"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:26
|
||||
msgid ""
|
||||
"Start Ruijie 802.1X Authentication based on MentoHUST when the router is "
|
||||
"booting."
|
||||
msgstr "开机自动启动基于MentoHUST的锐捷802.1X认证客户端。"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:28
|
||||
msgid "Enable IPv6 NAT"
|
||||
msgstr "开启IPv6 NAT"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:28
|
||||
msgid "Enable IPv6 NAT pass-through based on ip6tables MASQUERADE."
|
||||
msgstr "开启基于ip6tables Masquerade技术的IPv6 NAT穿透。"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:30
|
||||
msgid "Config Authentication"
|
||||
msgstr "配置认证参数"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:30
|
||||
msgid "The options below are all of MentoHUST's arguments."
|
||||
msgstr "以下是全部的MentoHUST认证参数。"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:34
|
||||
msgid "Username"
|
||||
msgstr "用户名"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:36
|
||||
msgid "Password"
|
||||
msgstr "密码"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:41
|
||||
msgid "Interfaces"
|
||||
msgstr "网卡"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:51
|
||||
msgid "IP"
|
||||
msgstr "IP地址"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:51
|
||||
msgid "default to localhost's IP"
|
||||
msgstr "默认为localhost的IP地址"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:53
|
||||
msgid "Netmask"
|
||||
msgstr "掩码"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:53
|
||||
msgid "default to localhost's netmask"
|
||||
msgstr "默认为localhost的掩码"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:55
|
||||
msgid "Gateway"
|
||||
msgstr "网关"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:55
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:57
|
||||
msgid "default to 0.0.0.0"
|
||||
msgstr "默认为0.0.0.0"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:57
|
||||
msgid "DNS"
|
||||
msgstr "DNS服务器"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:59
|
||||
msgid "Ping host"
|
||||
msgstr "Ping主机"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:59
|
||||
msgid "default to 0.0.0.0,i.e. disable this function"
|
||||
msgstr "默认为0.0.0.0,即关闭该功能"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:61
|
||||
msgid "Authenticate timeout(s)"
|
||||
msgstr "认证超时(秒)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:61
|
||||
msgid "default to 8s"
|
||||
msgstr "默认为8秒"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:63
|
||||
msgid "Heartbeat timeout(s)"
|
||||
msgstr "心跳包超时(秒)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:63
|
||||
msgid "default to 30s"
|
||||
msgstr "默认为30秒"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:65
|
||||
msgid "Timeout on failure(s)"
|
||||
msgstr "失败等待(秒)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:65
|
||||
msgid "default to 15s"
|
||||
msgstr "默认为15秒"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:67
|
||||
msgid "Max failure times"
|
||||
msgstr "允许失败次数"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:67
|
||||
msgid "0 means no limit,default to 8"
|
||||
msgstr "0表示无限制,默认为8"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:69
|
||||
msgid "mulcast address"
|
||||
msgstr "多播地址"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:69
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:75
|
||||
msgid "default to 1"
|
||||
msgstr "默认为1"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:70
|
||||
msgid "0(standard)"
|
||||
msgstr "0(标准)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:71
|
||||
msgid "1(ruijjie)"
|
||||
msgstr "1(锐捷)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:72
|
||||
msgid "2(saier)"
|
||||
msgstr "2(赛尔)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:75
|
||||
msgid "DHCP type"
|
||||
msgstr "DHCP方式"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:76
|
||||
msgid "0(not in used)"
|
||||
msgstr "0(不使用)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:77
|
||||
msgid "1(secondary authenticate)"
|
||||
msgstr "1(二次认证)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:78
|
||||
msgid "2(post authenticate)"
|
||||
msgstr "3(认证后)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:79
|
||||
msgid "3(pre authenticate)"
|
||||
msgstr "3(认证前)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:82
|
||||
msgid "run in daemon mode"
|
||||
msgstr "后台运行模式"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:82
|
||||
msgid "default to 3"
|
||||
msgstr "默认为3"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:83
|
||||
msgid "0(no)"
|
||||
msgstr "0(不使用后台模式)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:84
|
||||
msgid "1(yes,turn off output)"
|
||||
msgstr "1(后台模式,关闭输出)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:85
|
||||
msgid "2(yes,persevere output)"
|
||||
msgstr "2(后台模式,保留输出)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:86
|
||||
msgid "3(yes,output to file)"
|
||||
msgstr "3(后台模式,输出到日志文件)"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:89
|
||||
msgid "display notification"
|
||||
msgstr "显示通知"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:89
|
||||
msgid "0(no),1-20(yes),default to 0"
|
||||
msgstr "0(不使用),1-20(使用),默认为0"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:91
|
||||
msgid "client version"
|
||||
msgstr "客户端版本号"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:91
|
||||
msgid "default to 0.00,compatible with xrgsu"
|
||||
msgstr "默认为0.00,表示兼容xrgsu"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:93
|
||||
msgid "customized data file"
|
||||
msgstr "自定义数据文件"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:93
|
||||
msgid "not in used by default"
|
||||
msgstr "默认不使用"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:96
|
||||
msgid "DHCP script"
|
||||
msgstr "DHCP脚本"
|
||||
|
||||
#: root/usr/lib/lua/luci/model/cbi/airwhu.lua:96
|
||||
msgid "use dhclient by default"
|
||||
msgstr "默认使用dhclient"
|
12
luci-app-airwhu/tools/po2lmo/Makefile
Normal file
12
luci-app-airwhu/tools/po2lmo/Makefile
Normal file
@ -0,0 +1,12 @@
|
||||
|
||||
INSTALL = install
|
||||
PREFIX = /usr/bin
|
||||
|
||||
po2lmo: src/po2lmo.o src/template_lmo.o
|
||||
$(CC) $(LDFLAGS) -o src/po2lmo src/po2lmo.o src/template_lmo.o
|
||||
|
||||
install:
|
||||
$(INSTALL) -m 755 src/po2lmo $(PREFIX)
|
||||
|
||||
clean:
|
||||
$(RM) src/po2lmo src/*.o
|
BIN
luci-app-airwhu/tools/po2lmo/src/po2lmo
Executable file
BIN
luci-app-airwhu/tools/po2lmo/src/po2lmo
Executable file
Binary file not shown.
247
luci-app-airwhu/tools/po2lmo/src/po2lmo.c
Normal file
247
luci-app-airwhu/tools/po2lmo/src/po2lmo.c
Normal file
@ -0,0 +1,247 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - PO to LMO conversion tool
|
||||
*
|
||||
* Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "template_lmo.h"
|
||||
|
||||
static void die(const char *msg)
|
||||
{
|
||||
fprintf(stderr, "Error: %s\n", msg);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void usage(const char *name)
|
||||
{
|
||||
fprintf(stderr, "Usage: %s input.po output.lmo\n", name);
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static void print(const void *ptr, size_t size, size_t nmemb, FILE *stream)
|
||||
{
|
||||
if( fwrite(ptr, size, nmemb, stream) == 0 )
|
||||
die("Failed to write stdout");
|
||||
}
|
||||
|
||||
static int extract_string(const char *src, char *dest, int len)
|
||||
{
|
||||
int pos = 0;
|
||||
int esc = 0;
|
||||
int off = -1;
|
||||
|
||||
for( pos = 0; (pos < strlen(src)) && (pos < len); pos++ )
|
||||
{
|
||||
if( (off == -1) && (src[pos] == '"') )
|
||||
{
|
||||
off = pos + 1;
|
||||
}
|
||||
else if( off >= 0 )
|
||||
{
|
||||
if( esc == 1 )
|
||||
{
|
||||
switch (src[pos])
|
||||
{
|
||||
case '"':
|
||||
case '\\':
|
||||
off++;
|
||||
break;
|
||||
}
|
||||
dest[pos-off] = src[pos];
|
||||
esc = 0;
|
||||
}
|
||||
else if( src[pos] == '\\' )
|
||||
{
|
||||
dest[pos-off] = src[pos];
|
||||
esc = 1;
|
||||
}
|
||||
else if( src[pos] != '"' )
|
||||
{
|
||||
dest[pos-off] = src[pos];
|
||||
}
|
||||
else
|
||||
{
|
||||
dest[pos-off] = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return (off > -1) ? strlen(dest) : -1;
|
||||
}
|
||||
|
||||
static int cmp_index(const void *a, const void *b)
|
||||
{
|
||||
uint32_t x = ((const lmo_entry_t *)a)->key_id;
|
||||
uint32_t y = ((const lmo_entry_t *)b)->key_id;
|
||||
|
||||
if (x < y)
|
||||
return -1;
|
||||
else if (x > y)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void print_uint32(uint32_t x, FILE *out)
|
||||
{
|
||||
uint32_t y = htonl(x);
|
||||
print(&y, sizeof(uint32_t), 1, out);
|
||||
}
|
||||
|
||||
static void print_index(void *array, int n, FILE *out)
|
||||
{
|
||||
lmo_entry_t *e;
|
||||
|
||||
qsort(array, n, sizeof(*e), cmp_index);
|
||||
|
||||
for (e = array; n > 0; n--, e++)
|
||||
{
|
||||
print_uint32(e->key_id, out);
|
||||
print_uint32(e->val_id, out);
|
||||
print_uint32(e->offset, out);
|
||||
print_uint32(e->length, out);
|
||||
}
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
char line[4096];
|
||||
char key[4096];
|
||||
char val[4096];
|
||||
char tmp[4096];
|
||||
int state = 0;
|
||||
int offset = 0;
|
||||
int length = 0;
|
||||
int n_entries = 0;
|
||||
void *array = NULL;
|
||||
lmo_entry_t *entry = NULL;
|
||||
uint32_t key_id, val_id;
|
||||
|
||||
FILE *in;
|
||||
FILE *out;
|
||||
|
||||
if( (argc != 3) || ((in = fopen(argv[1], "r")) == NULL) || ((out = fopen(argv[2], "w")) == NULL) )
|
||||
usage(argv[0]);
|
||||
|
||||
memset(line, 0, sizeof(key));
|
||||
memset(key, 0, sizeof(val));
|
||||
memset(val, 0, sizeof(val));
|
||||
|
||||
while( (NULL != fgets(line, sizeof(line), in)) || (state >= 2 && feof(in)) )
|
||||
{
|
||||
if( state == 0 && strstr(line, "msgid \"") == line )
|
||||
{
|
||||
switch(extract_string(line, key, sizeof(key)))
|
||||
{
|
||||
case -1:
|
||||
die("Syntax error in msgid");
|
||||
case 0:
|
||||
state = 1;
|
||||
break;
|
||||
default:
|
||||
state = 2;
|
||||
}
|
||||
}
|
||||
else if( state == 1 || state == 2 )
|
||||
{
|
||||
if( strstr(line, "msgstr \"") == line || state == 2 )
|
||||
{
|
||||
switch(extract_string(line, val, sizeof(val)))
|
||||
{
|
||||
case -1:
|
||||
state = 4;
|
||||
break;
|
||||
default:
|
||||
state = 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||
{
|
||||
case -1:
|
||||
state = 2;
|
||||
break;
|
||||
default:
|
||||
strcat(key, tmp);
|
||||
}
|
||||
}
|
||||
}
|
||||
else if( state == 3 )
|
||||
{
|
||||
switch(extract_string(line, tmp, sizeof(tmp)))
|
||||
{
|
||||
case -1:
|
||||
state = 4;
|
||||
break;
|
||||
default:
|
||||
strcat(val, tmp);
|
||||
}
|
||||
}
|
||||
|
||||
if( state == 4 )
|
||||
{
|
||||
if( strlen(key) > 0 && strlen(val) > 0 )
|
||||
{
|
||||
key_id = sfh_hash(key, strlen(key));
|
||||
val_id = sfh_hash(val, strlen(val));
|
||||
|
||||
if( key_id != val_id )
|
||||
{
|
||||
n_entries++;
|
||||
array = realloc(array, n_entries * sizeof(lmo_entry_t));
|
||||
entry = (lmo_entry_t *)array + n_entries - 1;
|
||||
|
||||
if (!array)
|
||||
die("Out of memory");
|
||||
|
||||
entry->key_id = key_id;
|
||||
entry->val_id = val_id;
|
||||
entry->offset = offset;
|
||||
entry->length = strlen(val);
|
||||
|
||||
length = strlen(val) + ((4 - (strlen(val) % 4)) % 4);
|
||||
|
||||
print(val, length, 1, out);
|
||||
offset += length;
|
||||
}
|
||||
}
|
||||
|
||||
state = 0;
|
||||
memset(key, 0, sizeof(key));
|
||||
memset(val, 0, sizeof(val));
|
||||
}
|
||||
|
||||
memset(line, 0, sizeof(line));
|
||||
}
|
||||
|
||||
print_index(array, n_entries, out);
|
||||
|
||||
if( offset > 0 )
|
||||
{
|
||||
print_uint32(offset, out);
|
||||
fsync(fileno(out));
|
||||
fclose(out);
|
||||
}
|
||||
else
|
||||
{
|
||||
fclose(out);
|
||||
unlink(argv[2]);
|
||||
}
|
||||
|
||||
fclose(in);
|
||||
return(0);
|
||||
}
|
BIN
luci-app-airwhu/tools/po2lmo/src/po2lmo.o
Normal file
BIN
luci-app-airwhu/tools/po2lmo/src/po2lmo.o
Normal file
Binary file not shown.
328
luci-app-airwhu/tools/po2lmo/src/template_lmo.c
Normal file
328
luci-app-airwhu/tools/po2lmo/src/template_lmo.c
Normal file
@ -0,0 +1,328 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - Base functions
|
||||
*
|
||||
* Copyright (C) 2009-2010 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#include "template_lmo.h"
|
||||
|
||||
/*
|
||||
* Hash function from http://www.azillionmonkeys.com/qed/hash.html
|
||||
* Copyright (C) 2004-2008 by Paul Hsieh
|
||||
*/
|
||||
|
||||
uint32_t sfh_hash(const char *data, int len)
|
||||
{
|
||||
uint32_t hash = len, tmp;
|
||||
int rem;
|
||||
|
||||
if (len <= 0 || data == NULL) return 0;
|
||||
|
||||
rem = len & 3;
|
||||
len >>= 2;
|
||||
|
||||
/* Main loop */
|
||||
for (;len > 0; len--) {
|
||||
hash += sfh_get16(data);
|
||||
tmp = (sfh_get16(data+2) << 11) ^ hash;
|
||||
hash = (hash << 16) ^ tmp;
|
||||
data += 2*sizeof(uint16_t);
|
||||
hash += hash >> 11;
|
||||
}
|
||||
|
||||
/* Handle end cases */
|
||||
switch (rem) {
|
||||
case 3: hash += sfh_get16(data);
|
||||
hash ^= hash << 16;
|
||||
hash ^= data[sizeof(uint16_t)] << 18;
|
||||
hash += hash >> 11;
|
||||
break;
|
||||
case 2: hash += sfh_get16(data);
|
||||
hash ^= hash << 11;
|
||||
hash += hash >> 17;
|
||||
break;
|
||||
case 1: hash += *data;
|
||||
hash ^= hash << 10;
|
||||
hash += hash >> 1;
|
||||
}
|
||||
|
||||
/* Force "avalanching" of final 127 bits */
|
||||
hash ^= hash << 3;
|
||||
hash += hash >> 5;
|
||||
hash ^= hash << 4;
|
||||
hash += hash >> 17;
|
||||
hash ^= hash << 25;
|
||||
hash += hash >> 6;
|
||||
|
||||
return hash;
|
||||
}
|
||||
|
||||
uint32_t lmo_canon_hash(const char *str, int len)
|
||||
{
|
||||
char res[4096];
|
||||
char *ptr, prev;
|
||||
int off;
|
||||
|
||||
if (!str || len >= sizeof(res))
|
||||
return 0;
|
||||
|
||||
for (prev = ' ', ptr = res, off = 0; off < len; prev = *str, off++, str++)
|
||||
{
|
||||
if (isspace(*str))
|
||||
{
|
||||
if (!isspace(prev))
|
||||
*ptr++ = ' ';
|
||||
}
|
||||
else
|
||||
{
|
||||
*ptr++ = *str;
|
||||
}
|
||||
}
|
||||
|
||||
if ((ptr > res) && isspace(*(ptr-1)))
|
||||
ptr--;
|
||||
|
||||
return sfh_hash(res, ptr - res);
|
||||
}
|
||||
|
||||
lmo_archive_t * lmo_open(const char *file)
|
||||
{
|
||||
int in = -1;
|
||||
uint32_t idx_offset = 0;
|
||||
struct stat s;
|
||||
|
||||
lmo_archive_t *ar = NULL;
|
||||
|
||||
if (stat(file, &s) == -1)
|
||||
goto err;
|
||||
|
||||
if ((in = open(file, O_RDONLY)) == -1)
|
||||
goto err;
|
||||
|
||||
if ((ar = (lmo_archive_t *)malloc(sizeof(*ar))) != NULL)
|
||||
{
|
||||
memset(ar, 0, sizeof(*ar));
|
||||
|
||||
ar->fd = in;
|
||||
ar->size = s.st_size;
|
||||
|
||||
fcntl(ar->fd, F_SETFD, fcntl(ar->fd, F_GETFD) | FD_CLOEXEC);
|
||||
|
||||
if ((ar->mmap = mmap(NULL, ar->size, PROT_READ, MAP_SHARED, ar->fd, 0)) == MAP_FAILED)
|
||||
goto err;
|
||||
|
||||
idx_offset = ntohl(*((const uint32_t *)
|
||||
(ar->mmap + ar->size - sizeof(uint32_t))));
|
||||
|
||||
if (idx_offset >= ar->size)
|
||||
goto err;
|
||||
|
||||
ar->index = (lmo_entry_t *)(ar->mmap + idx_offset);
|
||||
ar->length = (ar->size - idx_offset - sizeof(uint32_t)) / sizeof(lmo_entry_t);
|
||||
ar->end = ar->mmap + ar->size;
|
||||
|
||||
return ar;
|
||||
}
|
||||
|
||||
err:
|
||||
if (in > -1)
|
||||
close(in);
|
||||
|
||||
if (ar != NULL)
|
||||
{
|
||||
if ((ar->mmap != NULL) && (ar->mmap != MAP_FAILED))
|
||||
munmap(ar->mmap, ar->size);
|
||||
|
||||
free(ar);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void lmo_close(lmo_archive_t *ar)
|
||||
{
|
||||
if (ar != NULL)
|
||||
{
|
||||
if ((ar->mmap != NULL) && (ar->mmap != MAP_FAILED))
|
||||
munmap(ar->mmap, ar->size);
|
||||
|
||||
close(ar->fd);
|
||||
free(ar);
|
||||
|
||||
ar = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
lmo_catalog_t *_lmo_catalogs = NULL;
|
||||
lmo_catalog_t *_lmo_active_catalog = NULL;
|
||||
|
||||
int lmo_load_catalog(const char *lang, const char *dir)
|
||||
{
|
||||
DIR *dh = NULL;
|
||||
char pattern[16];
|
||||
char path[PATH_MAX];
|
||||
struct dirent *de = NULL;
|
||||
|
||||
lmo_archive_t *ar = NULL;
|
||||
lmo_catalog_t *cat = NULL;
|
||||
|
||||
if (!lmo_change_catalog(lang))
|
||||
return 0;
|
||||
|
||||
if (!dir || !(dh = opendir(dir)))
|
||||
goto err;
|
||||
|
||||
if (!(cat = malloc(sizeof(*cat))))
|
||||
goto err;
|
||||
|
||||
memset(cat, 0, sizeof(*cat));
|
||||
|
||||
snprintf(cat->lang, sizeof(cat->lang), "%s", lang);
|
||||
snprintf(pattern, sizeof(pattern), "*.%s.lmo", lang);
|
||||
|
||||
while ((de = readdir(dh)) != NULL)
|
||||
{
|
||||
if (!fnmatch(pattern, de->d_name, 0))
|
||||
{
|
||||
snprintf(path, sizeof(path), "%s/%s", dir, de->d_name);
|
||||
ar = lmo_open(path);
|
||||
|
||||
if (ar)
|
||||
{
|
||||
ar->next = cat->archives;
|
||||
cat->archives = ar;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
closedir(dh);
|
||||
|
||||
cat->next = _lmo_catalogs;
|
||||
_lmo_catalogs = cat;
|
||||
|
||||
if (!_lmo_active_catalog)
|
||||
_lmo_active_catalog = cat;
|
||||
|
||||
return 0;
|
||||
|
||||
err:
|
||||
if (dh) closedir(dh);
|
||||
if (cat) free(cat);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int lmo_change_catalog(const char *lang)
|
||||
{
|
||||
lmo_catalog_t *cat;
|
||||
|
||||
for (cat = _lmo_catalogs; cat; cat = cat->next)
|
||||
{
|
||||
if (!strncmp(cat->lang, lang, sizeof(cat->lang)))
|
||||
{
|
||||
_lmo_active_catalog = cat;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static lmo_entry_t * lmo_find_entry(lmo_archive_t *ar, uint32_t hash)
|
||||
{
|
||||
unsigned int m, l, r;
|
||||
uint32_t k;
|
||||
|
||||
l = 0;
|
||||
r = ar->length - 1;
|
||||
|
||||
while (1)
|
||||
{
|
||||
m = l + ((r - l) / 2);
|
||||
|
||||
if (r < l)
|
||||
break;
|
||||
|
||||
k = ntohl(ar->index[m].key_id);
|
||||
|
||||
if (k == hash)
|
||||
return &ar->index[m];
|
||||
|
||||
if (k > hash)
|
||||
{
|
||||
if (!m)
|
||||
break;
|
||||
|
||||
r = m - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l = m + 1;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int lmo_translate(const char *key, int keylen, char **out, int *outlen)
|
||||
{
|
||||
uint32_t hash;
|
||||
lmo_entry_t *e;
|
||||
lmo_archive_t *ar;
|
||||
|
||||
if (!key || !_lmo_active_catalog)
|
||||
return -2;
|
||||
|
||||
hash = lmo_canon_hash(key, keylen);
|
||||
|
||||
for (ar = _lmo_active_catalog->archives; ar; ar = ar->next)
|
||||
{
|
||||
if ((e = lmo_find_entry(ar, hash)) != NULL)
|
||||
{
|
||||
*out = ar->mmap + ntohl(e->offset);
|
||||
*outlen = ntohl(e->length);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
void lmo_close_catalog(const char *lang)
|
||||
{
|
||||
lmo_archive_t *ar, *next;
|
||||
lmo_catalog_t *cat, *prev;
|
||||
|
||||
for (prev = NULL, cat = _lmo_catalogs; cat; prev = cat, cat = cat->next)
|
||||
{
|
||||
if (!strncmp(cat->lang, lang, sizeof(cat->lang)))
|
||||
{
|
||||
if (prev)
|
||||
prev->next = cat->next;
|
||||
else
|
||||
_lmo_catalogs = cat->next;
|
||||
|
||||
for (ar = cat->archives; ar; ar = next)
|
||||
{
|
||||
next = ar->next;
|
||||
lmo_close(ar);
|
||||
}
|
||||
|
||||
free(cat);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
92
luci-app-airwhu/tools/po2lmo/src/template_lmo.h
Normal file
92
luci-app-airwhu/tools/po2lmo/src/template_lmo.h
Normal file
@ -0,0 +1,92 @@
|
||||
/*
|
||||
* lmo - Lua Machine Objects - General header
|
||||
*
|
||||
* Copyright (C) 2009-2012 Jo-Philipp Wich <xm@subsignal.org>
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
#ifndef _TEMPLATE_LMO_H_
|
||||
#define _TEMPLATE_LMO_H_
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <unistd.h>
|
||||
#include <errno.h>
|
||||
#include <fnmatch.h>
|
||||
#include <dirent.h>
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
#if (defined(__GNUC__) && defined(__i386__))
|
||||
#define sfh_get16(d) (*((const uint16_t *) (d)))
|
||||
#else
|
||||
#define sfh_get16(d) ((((uint32_t)(((const uint8_t *)(d))[1])) << 8)\
|
||||
+(uint32_t)(((const uint8_t *)(d))[0]) )
|
||||
#endif
|
||||
|
||||
|
||||
struct lmo_entry {
|
||||
uint32_t key_id;
|
||||
uint32_t val_id;
|
||||
uint32_t offset;
|
||||
uint32_t length;
|
||||
} __attribute__((packed));
|
||||
|
||||
typedef struct lmo_entry lmo_entry_t;
|
||||
|
||||
|
||||
struct lmo_archive {
|
||||
int fd;
|
||||
int length;
|
||||
uint32_t size;
|
||||
lmo_entry_t *index;
|
||||
char *mmap;
|
||||
char *end;
|
||||
struct lmo_archive *next;
|
||||
};
|
||||
|
||||
typedef struct lmo_archive lmo_archive_t;
|
||||
|
||||
|
||||
struct lmo_catalog {
|
||||
char lang[6];
|
||||
struct lmo_archive *archives;
|
||||
struct lmo_catalog *next;
|
||||
};
|
||||
|
||||
typedef struct lmo_catalog lmo_catalog_t;
|
||||
|
||||
|
||||
uint32_t sfh_hash(const char *data, int len);
|
||||
uint32_t lmo_canon_hash(const char *data, int len);
|
||||
|
||||
lmo_archive_t * lmo_open(const char *file);
|
||||
void lmo_close(lmo_archive_t *ar);
|
||||
|
||||
|
||||
extern lmo_catalog_t *_lmo_catalogs;
|
||||
extern lmo_catalog_t *_lmo_active_catalog;
|
||||
|
||||
int lmo_load_catalog(const char *lang, const char *dir);
|
||||
int lmo_change_catalog(const char *lang);
|
||||
int lmo_translate(const char *key, int keylen, char **out, int *outlen);
|
||||
void lmo_close_catalog(const char *lang);
|
||||
|
||||
#endif
|
BIN
luci-app-airwhu/tools/po2lmo/src/template_lmo.o
Normal file
BIN
luci-app-airwhu/tools/po2lmo/src/template_lmo.o
Normal file
Binary file not shown.
2
luci-app-autoipsetadder/.gitattributes
vendored
Normal file
2
luci-app-autoipsetadder/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
2
luci-app-autoipsetadder/.gitignore
vendored
Normal file
2
luci-app-autoipsetadder/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
*.bak
|
64
luci-app-autoipsetadder/Makefile
Executable file
64
luci-app-autoipsetadder/Makefile
Executable file
@ -0,0 +1,64 @@
|
||||
# Copyright (C) 2018-2019 Lienol
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-autoipsetadder
|
||||
PKG_VERSION:=1.0
|
||||
PKG_RELEASE:=7
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/luci-app-autoipsetadder
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=LuCI Support for autoipsetadder
|
||||
PKGARCH:=all
|
||||
DEPENDS:= +httping +curl
|
||||
endef
|
||||
|
||||
define Package/luci-app-autoipsetadder/description
|
||||
LuCI support for autoipsetadder
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/luci-app-autoipsetadder/conffiles
|
||||
/etc/config/autoipsetadder
|
||||
endef
|
||||
|
||||
define Package/luci-app-autoipsetadder/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
|
||||
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
|
||||
$(INSTALL_DIR) $(1)/
|
||||
cp -pR ./root/* $(1)/
|
||||
endef
|
||||
|
||||
define Package/luci-app-autoipsetadder/postinst
|
||||
#!/bin/sh
|
||||
/etc/init.d/autoipsetadder enable >/dev/null 2>&1
|
||||
/etc/init.d/autoipsetadder start
|
||||
rm -f /tmp/luci-indexcache
|
||||
rm -f /tmp/luci-modulecache/*
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-autoipsetadder/prerm
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
/etc/init.d/autoipsetadder disable
|
||||
/etc/init.d/autoipsetadder stop
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-autoipsetadder))
|
4
luci-app-autoipsetadder/README.md
Executable file
4
luci-app-autoipsetadder/README.md
Executable file
@ -0,0 +1,4 @@
|
||||
# luci-app-autoipsetadder
|
||||
需要ipset china 和 ipset gfwlist<br>
|
||||
更多信息https://github.com/rufengsuixing/auto-ipsetadder-for-openwrt
|
||||
![Screenshot_2019-12-27 newifi-d1 - 基础设置 - LuCI(1)](https://user-images.githubusercontent.com/22387141/71496667-63eafb80-288f-11ea-93b7-52b154450d2b.png)
|
56
luci-app-autoipsetadder/luasrc/controller/autoipsetadder.lua
Executable file
56
luci-app-autoipsetadder/luasrc/controller/autoipsetadder.lua
Executable file
@ -0,0 +1,56 @@
|
||||
module("luci.controller.autoipsetadder",package.seeall)
|
||||
local io = require "io"
|
||||
local fs=require"nixio.fs"
|
||||
local sys=require"luci.sys"
|
||||
local uci=require"luci.model.uci".cursor()
|
||||
function index()
|
||||
entry({"admin","services","autoipsetadder"},firstchild(),_("autoipsetadder"),30).dependent=true
|
||||
entry({"admin","services","autoipsetadder","autoipsetadder"},cbi("autoipsetadder"),_("Base Setting"),1)
|
||||
entry({"admin","services","autoipsetadder","status"},call("act_status")).leaf=true
|
||||
entry({"admin", "services", "autoipsetadder", "getlog"}, call("get_log"))
|
||||
entry({"admin", "services", "autoipsetadder", "dodellog"}, call("do_del_log"))
|
||||
entry({"admin", "services", "autoipsetadder", "debugip"}, call("do_debug_ip"))
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running=luci.sys.call("pgrep -f /usr/bin/autoipsetadder/autoaddlist.sh >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
||||
function do_del_log()
|
||||
local logfile=uci:get("autoipsetadder","autoipsetadder","logfile") or "/tmp/addlist.log"
|
||||
nixio.fs.writefile(logfile,"")
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write('')
|
||||
end
|
||||
function do_debug_ip()
|
||||
luci.http.prepare_content("text/plain; charset=utf-8")
|
||||
local a=sys.exec("/usr/bin/autoipsetadder/debugip.sh")
|
||||
if (a=="") then
|
||||
a="noproblem"
|
||||
end
|
||||
luci.http.write(a)
|
||||
end
|
||||
function get_log()
|
||||
local logfile,fdp
|
||||
logfile=uci:get("autoipsetadder","autoipsetadder","logfile") or "/tmp/addlist.log"
|
||||
luci.http.prepare_content("text/plain; charset=utf-8")
|
||||
if not fs.access(logfile) then
|
||||
luci.http.write("")
|
||||
return
|
||||
end
|
||||
if fs.access("/var/run/lucilogreload") then
|
||||
fdp=0
|
||||
fs.remove("/var/run/lucilogreload")
|
||||
else
|
||||
fdp=tonumber(fs.readfile("/var/run/lucilogpos")) or 0
|
||||
end
|
||||
local f=io.open(logfile, "r+")
|
||||
f:seek("set",fdp)
|
||||
local a=f:read(2048000) or ""
|
||||
fdp=f:seek()
|
||||
fs.writefile("/var/run/lucilogpos",tostring(fdp))
|
||||
f:close()
|
||||
luci.http.write(a)
|
||||
end
|
97
luci-app-autoipsetadder/luasrc/model/cbi/autoipsetadder.lua
Executable file
97
luci-app-autoipsetadder/luasrc/model/cbi/autoipsetadder.lua
Executable file
@ -0,0 +1,97 @@
|
||||
require("luci.sys")
|
||||
require("luci.util")
|
||||
local fs=require"nixio.fs"
|
||||
local uci=require"luci.model.uci".cursor()
|
||||
local m,s,o
|
||||
m = Map("autoipsetadder", translate("ipsetautoadder"))
|
||||
m.description = translate("自动将联不通的域名加入ipset")
|
||||
m:section(SimpleSection).template = "autoipsetadder/status"
|
||||
|
||||
s = m:section(TypedSection, "autoipsetadder")
|
||||
s.anonymous=true
|
||||
s.addremove=false
|
||||
---- enable
|
||||
o = s:option(Flag, "enabled", translate("启用"))
|
||||
o.default = 0
|
||||
o.rmempty = false
|
||||
---- logview
|
||||
o=s:option(TextValue, "show", "日志")
|
||||
o.template = "autoipsetadder/check"
|
||||
---- logpath
|
||||
o = s:option(Value, "logfile", translate("Runtime log file"))
|
||||
o.datatype = "string"
|
||||
o.default="/tmp/addlist.log"
|
||||
o.optional = false
|
||||
o.validate=function(self, value)
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
fs.rmdir(value)
|
||||
end
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
if m.message then
|
||||
m.message =m.message.."\nerror!log file is a dir"
|
||||
else
|
||||
m.message ="error!log file is a dir"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
return value
|
||||
end
|
||||
---- dnsmasq log
|
||||
o = s:option(Value, "dnslogfile", translate("dnsmasq log file"))
|
||||
o.datatype = "string"
|
||||
o.optional = false
|
||||
o.default="/tmp/dnsmasq.log"
|
||||
o.validate=function(self, value)
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
fs.rmdir(value)
|
||||
end
|
||||
if fs.stat(value,"type")=="dir" then
|
||||
if m.message then
|
||||
m.message =m.message.."\nerror!log file is a dir"
|
||||
else
|
||||
m.message ="error!log file is a dir"
|
||||
end
|
||||
return nil
|
||||
end
|
||||
return value
|
||||
end
|
||||
---- crontab
|
||||
o = s:option(MultiValue, "crontab", translate("Crontab task"),translate("Please change time and args in crontab"))
|
||||
o:value("autodeldnslog",translate("Auto del dnsmasq log"))
|
||||
o:value("autotaillog",translate("Auto tail runtime log"))
|
||||
o.widget = "checkbox"
|
||||
o.default = "autodeldnslog autotaillog"
|
||||
o.rmempty= true
|
||||
|
||||
o = s:option(MultiValue, "config", translate("the way add to gfwlist"))
|
||||
o:value("nochina",translate("no china ip"))
|
||||
o:value("pingadd",translate("5ping loss1-4"))
|
||||
o:value("packetpass",translate("packet >12 pass"))
|
||||
o.widget = "checkbox"
|
||||
o.default = "nochina pingadd packetpass"
|
||||
o.rmempty=true
|
||||
---- apply
|
||||
nixio.fs.writefile("/var/run/lucilogreload","")
|
||||
function m.on_commit(map)
|
||||
local ucitracktest=uci:get("autoipsetadder","autoipsetadder","ucitracktest")
|
||||
if ucitracktest=="1" then
|
||||
return
|
||||
elseif ucitracktest=="0" then
|
||||
io.popen("/etc/init.d/autoipsetadder reload &")
|
||||
else
|
||||
if (fs.access("/var/run/AdGucitest")) then
|
||||
uci:set("autoipsetadder","autoipsetadder","ucitracktest","0")
|
||||
io.popen("/etc/init.d/autoipsetadder reload &")
|
||||
else
|
||||
fs.writefile("/var/run/AdGucitest","")
|
||||
if (ucitracktest=="2") then
|
||||
uci:set("autoipsetadder","autoipsetadder","ucitracktest","1")
|
||||
else
|
||||
uci:set("autoipsetadder","autoipsetadder","ucitracktest","2")
|
||||
end
|
||||
end
|
||||
uci:save("autoipsetadder")
|
||||
uci:commit("autoipsetadder")
|
||||
end
|
||||
end
|
||||
return m
|
62
luci-app-autoipsetadder/luasrc/view/autoipsetadder/check.htm
Executable file
62
luci-app-autoipsetadder/luasrc/view/autoipsetadder/check.htm
Executable file
@ -0,0 +1,62 @@
|
||||
<%+cbi/valueheader%>
|
||||
<%uci=require"luci.model.uci".cursor()%>
|
||||
<%nixio=require"nixio"%>
|
||||
|
||||
<%if uci:get("autoipsetadder","autoipsetadder","enabled")=="1" then%>
|
||||
<textarea id="cbid.logview.1.conf" class="cbi-input-textarea" style="width: 100%;display:inline" data-update="change" rows="10" cols="60" readonly="readonly" > </textarea>
|
||||
<input type="checkbox" value="reverse" onclick=" return reverselog()" style="vertical-align:middle;height: auto;" checked><%:reverse%></input>
|
||||
<input type="button" class="cbi-button cbi-button-apply" id="apply_update_button" value="dellog" onclick=" return apply_del_log() "/>
|
||||
|
||||
<input type="button" class="cbi-button cbi-button-apply" id="apply_update_button" value="debug" onclick=" return debug_ip() "/>
|
||||
|
||||
<textarea id="cbid.logview.2.conf" class="cbi-input-textarea" style="width: 100%;display:none" data-update="change" rows="10" cols="60" readonly="readonly" > </textarea>
|
||||
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
var islogreverse = true;
|
||||
function apply_del_log(){
|
||||
XHR.get('<%=url([[admin]], [[services]], [[autoipsetadder]], [[dodellog]])%>',null,function(x, data){
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
lv.innerHTML="";
|
||||
}
|
||||
);
|
||||
return
|
||||
}
|
||||
function reverselog(){
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
lv.innerHTML=lv.innerHTML.split('\n').reverse().join('\n')
|
||||
if (islogreverse){
|
||||
islogreverse=false;
|
||||
}else{
|
||||
islogreverse=true;
|
||||
}
|
||||
return
|
||||
}
|
||||
function debug_ip(){
|
||||
var lv2 = document.getElementById('cbid.logview.2.conf');
|
||||
lv2.style.display="inline"
|
||||
XHR.get('<%=url([[admin]], [[services]], [[autoipsetadder]], [[debugip]])%>',null,function(x, data){
|
||||
var lv2 = document.getElementById('cbid.logview.2.conf');
|
||||
lv2.innerHTML = x.responseText;
|
||||
}
|
||||
);
|
||||
return
|
||||
}
|
||||
function poll_check(){
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[autoipsetadder]], [[getlog]])%>', null,
|
||||
function(x, data) {
|
||||
var lv = document.getElementById('cbid.logview.1.conf');
|
||||
if (x.responseText && lv) {
|
||||
if (islogreverse){
|
||||
lv.innerHTML = x.responseText.split('\n').reverse().join('\n')+lv.innerHTML;
|
||||
}else{
|
||||
lv.innerHTML += x.responseText;
|
||||
}
|
||||
}
|
||||
}
|
||||
);}
|
||||
poll_check();
|
||||
|
||||
//]]>
|
||||
</script>
|
||||
<%end%>
|
||||
<%+cbi/valuefooter%>
|
22
luci-app-autoipsetadder/luasrc/view/autoipsetadder/status.htm
Executable file
22
luci-app-autoipsetadder/luasrc/view/autoipsetadder/status.htm
Executable file
@ -0,0 +1,22 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[autoipsetadder]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('autoipsetadder_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>autoipsetadder <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>autoipsetadder <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="autoipsetadder_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
2
luci-app-autoipsetadder/root/etc/config/autoipsetadder
Executable file
2
luci-app-autoipsetadder/root/etc/config/autoipsetadder
Executable file
@ -0,0 +1,2 @@
|
||||
config autoipsetadder 'autoipsetadder'
|
||||
option enabled '0'
|
126
luci-app-autoipsetadder/root/etc/init.d/autoipsetadder
Executable file
126
luci-app-autoipsetadder/root/etc/init.d/autoipsetadder
Executable file
@ -0,0 +1,126 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
|
||||
USE_PROCD=1
|
||||
|
||||
START=99
|
||||
STOP=01
|
||||
CRON_FILE=/etc/crontabs/root
|
||||
CONFIGURATION=autoipsetadder
|
||||
EXTRA_COMMANDS="test_crontab"
|
||||
EXTRA_HELP="
|
||||
test_crontab"
|
||||
set_dnsmasq_log()
|
||||
{
|
||||
sed -i '/log-facility/d' /etc/dnsmasq.conf
|
||||
sed -i '/log-queries/d' /etc/dnsmasq.conf
|
||||
uci set dhcp.@dnsmasq[0].logfacility='/tmp/dnsmasq.log'
|
||||
uci delete dhcp.@dnsmasq[0].logqueries
|
||||
echo log-queries >> /etc/dnsmasq.conf
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq reload
|
||||
}
|
||||
|
||||
stop_dnsmasq_log()
|
||||
{
|
||||
sed -i '/log-queries/d' /etc/dnsmasq.conf
|
||||
uci delete dhcp.@dnsmasq[0].logfacility
|
||||
uci commit dhcp
|
||||
/etc/init.d/dnsmasq reload
|
||||
}
|
||||
|
||||
reload_service()
|
||||
{
|
||||
rm -f /var/run/AdGucitest 2>/dev/null
|
||||
kill $(cat /var/run/autoipsetadder.pid)
|
||||
start
|
||||
}
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "$CONFIGURATION"
|
||||
}
|
||||
start_service() {
|
||||
# Reading config
|
||||
config_load "${CONFIGURATION}"
|
||||
mkdir -p /tmp/run/autoipsetadder
|
||||
local enabled
|
||||
config_get_bool enabled $CONFIGURATION enabled 0
|
||||
do_crontab
|
||||
if [ "$enabled" == "1" ]; then
|
||||
set_dnsmasq_log
|
||||
procd_open_instance
|
||||
procd_set_param respawn
|
||||
# pass config to script on start
|
||||
procd_set_param command sh /usr/bin/autoipsetadder/autoaddlist.sh
|
||||
procd_close_instance
|
||||
echo "autoipsetadder turn on"
|
||||
echo "enabled=$enabled"
|
||||
else
|
||||
stop_dnsmasq_log
|
||||
echo "autoipsetadder turn off"
|
||||
echo "enabled=$enabled"
|
||||
fi
|
||||
}
|
||||
|
||||
stop_service()
|
||||
{
|
||||
config_load "${CONFIGURATION}"
|
||||
stop_dnsmasq_log
|
||||
do_crontab
|
||||
kill $(cat /var/run/autoipsetadder.pid)
|
||||
echo "autoipsetadder turn off"
|
||||
echo "enabled="$enabled""
|
||||
}
|
||||
do_crontab(){
|
||||
config_get_bool enabled $CONFIGURATION enabled 0
|
||||
#config_get logfile $CONFIGURATION logfile "/tmp/addlist.log"
|
||||
#config_get dnslogfile $CONFIGURATION dnslogfile "/tmp/dnsmasq.log"
|
||||
config_get crontab $CONFIGURATION crontab ""
|
||||
cronreload=0
|
||||
findstr="echo qingkong > \$(uci get autoipsetadder.autoipsetadder.dnslogfile)"
|
||||
default="0 * * * * echo qingkong > \$(uci get autoipsetadder.autoipsetadder.dnslogfile)"
|
||||
#[ -n "$lastdnslogfile" ] && findstr="echo qingkong > $lastdnslogfile" && [ "$lastdnslogfile" != "$dnslogfile" ] && replace="${lastdnslogfile//\//\\/}/${dnslogfile//\//\\/}"
|
||||
[ "$enabled" == "0" ] || [ "${crontab//autodeldnslog/}" == "$crontab" ] && cronenable=0 || cronenable=1
|
||||
crontab_editor
|
||||
#[ "$lastdnslogfile" != "$dnslogfile" ] && uci set autoipsetadder.autoipsetadder.lastdnslogfile="$dnslogfile" && commit=1
|
||||
|
||||
findstr="/usr/bin/autoipsetadder/tailto.sh [0-9]* \$(uci get autoipsetadder.autoipsetadder.logfile)"
|
||||
default="0 0 * * * /usr/bin/autoipsetadder/tailto.sh 2000 \$(uci get autoipsetadder.autoipsetadder.logfile)"
|
||||
#[ -n "$lastlogfile" ] && findstr="/usr/bin/autoipsetadder/tailto.sh [0-9]* $lastlogfile" && [ "$lastlogfile" != "$logfile" ] && replace="${lastlogfile//\//\\/}/${logfile//\//\\/}"
|
||||
[ "$enabled" == "0" ] || [ "${crontab//autotaillog/}" == "$crontab" ] && cronenable=0 || cronenable=1
|
||||
crontab_editor
|
||||
#[ -n "$logfile" ] && [ "$lastlogfile" != "$logfile" ] && uci set autoipsetadder.autoipsetadder.lastlogfile="$logfile" && commit=1
|
||||
|
||||
[ "$cronreload" -gt 0 ] && /etc/init.d/cron restart
|
||||
#[ "$commit" -gt 0 ] && uci commit autoipsetadder
|
||||
}
|
||||
crontab_editor(){
|
||||
local testline reload
|
||||
local line="$(grep "$findstr" $CRON_FILE)"
|
||||
[ -n "$replace" ] && [ -n "$line" ] && eval testline="\${line//$replace}" && [ "$testline" != "$line" ] && line="$testline" && reload="1" && replace=""
|
||||
if [ "${line:0:1}" != "#" ]; then
|
||||
if [ $cronenable -eq 1 ]; then
|
||||
[ -z "$line" ] && line="$default" && reload="1"
|
||||
if [ -n "$reload" ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "$line" >> $CRON_FILE
|
||||
cronreload=$((cronreload+1))
|
||||
fi
|
||||
elif [ -n "$line" ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "#$line" >> $CRON_FILE
|
||||
cronreload=$((cronreload+1))
|
||||
fi
|
||||
else
|
||||
if [ $cronenable -eq 1 ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "${line:1}" >> $CRON_FILE
|
||||
cronreload=$((cronreload+1))
|
||||
elif [ -z "$reload" ]; then
|
||||
sed -i "\,$findstr,d" $CRON_FILE
|
||||
echo "$line" >> $CRON_FILE
|
||||
fi
|
||||
fi
|
||||
}
|
||||
test_crontab(){
|
||||
config_load "${CONFIGURATION}"
|
||||
do_crontab
|
||||
}
|
11
luci-app-autoipsetadder/root/etc/uci-defaults/40_luci-autoipsetadder
Executable file
11
luci-app-autoipsetadder/root/etc/uci-defaults/40_luci-autoipsetadder
Executable file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@autoipsetadder[-1]
|
||||
add ucitrack autoipsetadder
|
||||
set ucitrack.@autoipsetadder[-1].init=autoipsetadder
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
164
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/autoaddlist.sh
Executable file
164
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/autoaddlist.sh
Executable file
@ -0,0 +1,164 @@
|
||||
#!/bin/sh
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
logfile=$(uci get autoipsetadder.autoipsetadder.logfile)
|
||||
[ -z "$logfile" ] && logfile="/tmp/addlist.log"
|
||||
dnslogfile=$(uci get autoipsetadder.autoipsetadder.dnslogfile)
|
||||
[ -z "$logfile" ] && dnslogfile="/tmp/dnsmasq.log"
|
||||
config=$(uci get autoipsetadder.autoipsetadder.config 2>/dev/null)
|
||||
[ "${config//nochina/}" == "$config" ] && nochina="0" || nochina="1"
|
||||
[ "${config//packetpass/}" == "$config" ] && packetpass="0" || packetpass="1"
|
||||
(tail -F $dnslogfile & echo $! >/var/run/autoipsetadder.pid ) | awk -v nochina="$nochina" -v packetpass="$packetpass" -F "[, ]+" '/reply/{
|
||||
ip=$8;
|
||||
if (ip=="" || ip=="127.0.0.1"|| ip=="0.0.0.0")
|
||||
{
|
||||
next;
|
||||
}
|
||||
if (index(ip,"<CNAME>")!=0)
|
||||
{
|
||||
if (cname==1)
|
||||
{
|
||||
next;
|
||||
}
|
||||
cname=1;
|
||||
domain=$6;
|
||||
#第一次cname时锁定域名,防止解析cname对其改动
|
||||
next;
|
||||
}
|
||||
#以上获得上行是否为cname,本行不是cname执行以下内容
|
||||
#lastdomain记录上次非cname的域名,与本次域名对比
|
||||
if(lastdomain!=$6){
|
||||
for (ipindex in ipcache)
|
||||
{
|
||||
delete ipcache[ipindex];
|
||||
}
|
||||
ipcount=0;
|
||||
createpid=1;
|
||||
#上行非cname,并且不是同cname解析域名的多个ip,更新域名,清理同域名免试flag
|
||||
if (cname!=1)
|
||||
{
|
||||
domain=$6;
|
||||
testall=0;
|
||||
}}
|
||||
ipcount++;
|
||||
cname=0;
|
||||
lastdomain=$6
|
||||
#去除非ipv4
|
||||
if (index(ip,".")==0)
|
||||
{
|
||||
next;
|
||||
}
|
||||
#不重复探测ip
|
||||
if (!(ip in a))
|
||||
{
|
||||
#包数>12的同域名放过
|
||||
if (passdomain==domain)
|
||||
{
|
||||
print(ip" "domain" pass by same domain ok");
|
||||
a[ip]=domain;
|
||||
next;
|
||||
}
|
||||
if (nochina==1){
|
||||
"ipset test china "ip" 2>&1"| getline ipset;
|
||||
close("ipset test china "ip" 2>&1");
|
||||
if (index(ipset,"Warning")!=0){
|
||||
print("china "ip" pass");
|
||||
a[ip]=domain;
|
||||
next;
|
||||
}}
|
||||
"ipset test gfwlist "ip" 2>&1"| getline ipset;
|
||||
close("ipset test gfwlist "ip" 2>&1");
|
||||
if (index(ipset,"Warning")!=0){
|
||||
print("gfwlist "ip" pass");
|
||||
a[ip]=domain;
|
||||
next;
|
||||
}
|
||||
|
||||
#ip压入缓存,用于未检测到443/80的缓存
|
||||
ipcache[ipcount]=ip;
|
||||
if (testall==0){
|
||||
tryhttps=0;
|
||||
tryhttp=0;
|
||||
#探测 nf_conntrack 的443/80
|
||||
while ("grep "ip" /proc/net/nf_conntrack"| getline ret > 0)
|
||||
{
|
||||
split(ret, b," +");
|
||||
split(b[11], pagnum,"=");
|
||||
#包数>12的放过
|
||||
if (packetpass==1 && pagnum[2]>12)
|
||||
{
|
||||
print("pass by packets="pagnum[2]" "ip" "domain);
|
||||
for (ipindex in ipcache)
|
||||
{
|
||||
a[ipcache[ipindex]]=domain;
|
||||
delete ipcache[ipindex];
|
||||
}
|
||||
passdomain=domain;
|
||||
close("grep "ip" /proc/net/nf_conntrack");
|
||||
ipcount--;
|
||||
next;
|
||||
}
|
||||
if (b[8]=="dst="ip)
|
||||
{
|
||||
if (b[10]=="dport=443"){
|
||||
tryhttps=1;
|
||||
break;
|
||||
}
|
||||
else if (b[10]=="dport=80"){
|
||||
tryhttp=1;
|
||||
}
|
||||
}
|
||||
}
|
||||
close("grep "ip" /proc/net/nf_conntrack");
|
||||
}else{
|
||||
if (testall==443)
|
||||
{
|
||||
tryhttps=1
|
||||
}else{
|
||||
tryhttp=1
|
||||
}
|
||||
}
|
||||
if (tryhttps==1)
|
||||
{ if (createpid==1)
|
||||
{
|
||||
print "">"/tmp/run/autoipsetadder/"domain
|
||||
close("/tmp/run/autoipsetadder/"domain);
|
||||
print("create"domain);
|
||||
print(ip" "domain" 443"ipcount-1);
|
||||
a[ip]=domain;
|
||||
#正在使用的ip用最大延迟,最后探测,减少打断tcp的可能
|
||||
system("/usr/bin/autoipsetadder/testip.sh "ip" "domain" 443 "ipcount-1" &");
|
||||
delete ipcache[ipcount];
|
||||
createpid=0;
|
||||
}
|
||||
#未检测到443/80同域名缓存的ip进行测试,ipindex-1为测试延迟时间
|
||||
for (ipindex in ipcache){
|
||||
print(ipcache[ipindex]" "domain" 443 "ipindex-1);
|
||||
a[ipcache[ipindex]]=domain;
|
||||
system("/usr/bin/autoipsetadder/testip.sh "ipcache[ipindex]" "domain" 443 "ipindex-1" &");
|
||||
delete ipcache[ipindex];
|
||||
}
|
||||
#后续同域名ip免nf_conntrack测试
|
||||
testall=443;
|
||||
}
|
||||
else if (tryhttp==1)
|
||||
{
|
||||
if (createpid==1)
|
||||
{
|
||||
print "">"/tmp/run/autoipsetadder/"domain
|
||||
close("/tmp/run/autoipsetadder/"domain);
|
||||
print("create"domain);
|
||||
print(ip" "domain" 80 "ipcount-1);
|
||||
a[ip]=domain;
|
||||
system("/usr/bin/autoipsetadder/testip.sh "ip" "domain" 80 "ipcount-1" &");
|
||||
delete ipcache[ipcount];
|
||||
createpid=0;
|
||||
}
|
||||
for (ipindex in ipcache){
|
||||
print(ipcache[ipindex]" "domain" 80 "ipindex-1);
|
||||
a[ipcache[ipindex]]=domain;
|
||||
system("/usr/bin/autoipsetadder/testip.sh "ipcache[ipindex]" "domain" 80 "ipindex-1" &");
|
||||
delete ipcache[ipindex];
|
||||
}
|
||||
testall=80;
|
||||
}}
|
||||
}' >> $logfile
|
56
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/debugip.sh
Executable file
56
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/debugip.sh
Executable file
@ -0,0 +1,56 @@
|
||||
#!/bin/sh
|
||||
PATH="/usr/sbin:/usr/bin:/sbin:/bin"
|
||||
dlchina=$1;
|
||||
logfile=$(uci get autoipsetadder.autoipsetadder.logfile)
|
||||
[ -z "$logfile" ] && logfile="/tmp/addlist.log"
|
||||
|
||||
dnslogfile=$(uci get autoipsetadder.autoipsetadder.dnslogfile)
|
||||
[ -z "$logfile" ] && dnslogfile="/tmp/dnsmasq.log"
|
||||
|
||||
|
||||
ipset list gfwlist | awk -v dlchina="$dlchina" -v dnslogfile="$dnslogfile" -v logfile="$logfile" '{
|
||||
if (index($0,".")==0)
|
||||
{
|
||||
next;
|
||||
}
|
||||
if ($0=="127.0.0.1") {system("ipset d gfwlist 127.0.0.1");next;}
|
||||
"ipset test whitelist "$0" 2>&1"| getline ipset;
|
||||
close("ipset test whitelist "$0" 2>&1");
|
||||
if (index(ipset,"Warning")==0){
|
||||
white=0;
|
||||
}else{
|
||||
white=1;
|
||||
}
|
||||
"ipset test china "$0" 2>&1"| getline ipset;
|
||||
close("ipset test china "$0" 2>&1");
|
||||
if (index(ipset,"Warning")!=0){
|
||||
china=1;
|
||||
}
|
||||
else{
|
||||
china=0;
|
||||
}
|
||||
if (white==1)
|
||||
{
|
||||
if (china==0)
|
||||
{
|
||||
print("warning white ip not china"$0);
|
||||
ret=system("grep "$0" "logfile);
|
||||
if (ret!=0)
|
||||
{
|
||||
ret=system("grep "$0" "dnslogfile);
|
||||
}
|
||||
}
|
||||
}else if (china==1)
|
||||
{
|
||||
print("warning china ip not white"$0);
|
||||
ret=system("grep "$0" "logfile)
|
||||
if (ret!=0)
|
||||
{
|
||||
ret=system("grep "$0" "dnslogfile);
|
||||
}
|
||||
if (dlchina)
|
||||
{
|
||||
system("ipset del gfwlist "$0);
|
||||
}
|
||||
}
|
||||
}'
|
4
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/tailto.sh
Executable file
4
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/tailto.sh
Executable file
@ -0,0 +1,4 @@
|
||||
#!/bin/sh
|
||||
tail -n $1 "$2" > /var/run/tailtmp
|
||||
cat /var/run/tailtmp > "$2"
|
||||
rm /var/run/tailtmp
|
182
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/testip.sh
Executable file
182
luci-app-autoipsetadder/root/usr/bin/autoipsetadder/testip.sh
Executable file
@ -0,0 +1,182 @@
|
||||
#!/bin/sh
|
||||
config=$(uci get autoipsetadder.autoipsetadder.config 2>/dev/null)
|
||||
[ "${config//pingadd/}" == "$config" ] && pingadd="0" || pingadd="1"
|
||||
echo $* | awk -v pingadd="$pingadd" '{
|
||||
if ($4=="")
|
||||
{
|
||||
wait=0;
|
||||
}else
|
||||
{wait=$4;}
|
||||
system("sleep "wait);
|
||||
ERRNO="";
|
||||
pidfile="/tmp/run/autoipsetadder/"$2
|
||||
getline drop< pidfile;
|
||||
close(pidfile);
|
||||
if (ERRNO) {
|
||||
addlist=0;
|
||||
print("bypass"$1" "$2);
|
||||
next;}
|
||||
if ($3=="443")
|
||||
{
|
||||
cmd=("httping -c 1 -t 4 -l "$2" --divert-connect "$1);
|
||||
}
|
||||
else if ($3=="80")
|
||||
{
|
||||
cmd=("httping -c 1 -t 4 "$2" --divert-connect "$1);
|
||||
}
|
||||
addlist=0;
|
||||
slow=0;
|
||||
while ((cmd | getline ret) > 0)
|
||||
{
|
||||
if (addlist!=0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
else if (index(ret,"short read")!=0)
|
||||
{
|
||||
if (system("httping -q -c 1 -t 4 -l "$2" --divert-connect "$1)==0)
|
||||
{
|
||||
addlist=-1;
|
||||
break;
|
||||
}else{
|
||||
print("doname rst autoaddip "$1" "$2);
|
||||
addlist=1;
|
||||
}
|
||||
}
|
||||
else if (index(ret,"timeout")!=0)
|
||||
{
|
||||
while ((cmd | getline ret) > 0)
|
||||
{
|
||||
if (index(ret,"timeout")!=0)
|
||||
{
|
||||
print("direct so slow autoaddip "$1" "$2);
|
||||
addlist=1;
|
||||
slow=1;
|
||||
}
|
||||
}
|
||||
}else if (index(ret,"SSL handshake error: (null)")!=0)
|
||||
{
|
||||
if(system("curl -m 10 --resolve "$2":443:"$1" https://"$2" -o /dev/null 2>/dev/null")==0){
|
||||
addlist=-1;
|
||||
break;
|
||||
}
|
||||
}else if (index(ret,"Connection refused")!=0){
|
||||
print("direct Connection refused autoaddip"$1" "$2);
|
||||
addlist=1;
|
||||
}
|
||||
}
|
||||
close(cmd);
|
||||
|
||||
if (addlist!=1)
|
||||
{
|
||||
if (addlist==0){
|
||||
split(ret, c,"[ /]+");
|
||||
print(c[6]);
|
||||
if (c[6]=="failed,"){
|
||||
print("can not connect autoaddip "$1" "$2);
|
||||
addlist=1;
|
||||
}
|
||||
else if (c[6]+0>10000)
|
||||
{
|
||||
print("direct ssl so slow autoaddip "$1" "$2);
|
||||
addlist=1;
|
||||
}else{
|
||||
addlist=-1;}
|
||||
}
|
||||
if (addlist==-1 && pingadd==1)
|
||||
{
|
||||
while (("ping -c 5 -q -A "$1 | getline ret) > 0)
|
||||
{
|
||||
if (index(ret,"packet loss")!=0)
|
||||
{
|
||||
split(ret, p,"[ ]+");
|
||||
if (p[4]>0 && p[4]<5)
|
||||
{
|
||||
print("ping packet loss autoaddip "$1" "$2);
|
||||
pingloss=1;
|
||||
addlist=1;
|
||||
}else{pingloss=0;}
|
||||
break;
|
||||
}
|
||||
}
|
||||
close("ping -c 5 -q "$1);
|
||||
}
|
||||
}
|
||||
ERRNO="";
|
||||
if (pingloss!=1){
|
||||
getline drop< pidfile;
|
||||
close(pidfile);
|
||||
}
|
||||
if (ERRNO) {addlist=0;next;}
|
||||
if (addlist==1){
|
||||
system("ipset add gfwlist "$1);
|
||||
while ((cmd | getline ret) > 0)
|
||||
{
|
||||
if (addlist==1)
|
||||
{
|
||||
if (index(ret,"short read")!=0)
|
||||
{
|
||||
system("ipset del gfwlist "$1);
|
||||
print("doname proxy rst autodelip "$1" "$2);
|
||||
addlist=-2;
|
||||
}
|
||||
else if (index(ret,"SSL handshake error: (null)")!=0)
|
||||
{
|
||||
if(system("curl -m 10 --resolve "$2":443:"$1" https://"$2" -o /dev/null 2>/dev/null")==0)
|
||||
{
|
||||
addlist=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
close(cmd);
|
||||
if (addlist==1){
|
||||
split(ret, c,"[ /]+");
|
||||
print(c[6]);
|
||||
if (c[6]=="failed,")
|
||||
{
|
||||
system("ipset del gfwlist "$1);
|
||||
print("proxy can not connect autodelip "$1" "$2);
|
||||
addlist=-2;
|
||||
}else{
|
||||
addlist=2;
|
||||
}
|
||||
}
|
||||
}
|
||||
}END{
|
||||
if (addlist==2)
|
||||
{ if (pingloss==0){
|
||||
ERRNO="";
|
||||
getline drop< pidfile;
|
||||
if (ERRNO) {
|
||||
system("ipset del gfwlist "$1);
|
||||
print("cancel add myself "$1" "$2" due to one ip success direct");
|
||||
}else{
|
||||
print $1"\n">>pidfile;
|
||||
}
|
||||
close(pidfile);}
|
||||
}else if (addlist==-1)
|
||||
{
|
||||
print($1" "$2" direct success");
|
||||
while ((getline ret< pidfile) > 0)
|
||||
{
|
||||
if (ret!=""){
|
||||
system("ipset del gfwlist "ret);
|
||||
print("cancel add someone "ret" "$2" due to me"$1" success direct");
|
||||
}
|
||||
}
|
||||
close(pidfile);
|
||||
system("rm "pidfile" 2>/dev/null");
|
||||
print($1" del "$2);
|
||||
}else if (addlist==-2)
|
||||
{
|
||||
system("sleep 10");
|
||||
while ((getline ret< pidfile) > 0)
|
||||
{
|
||||
if (ret!=""){
|
||||
system("ipset add gfwlist "$1);
|
||||
print("add "ret" "$2" due to one ip success proxy");
|
||||
break;}
|
||||
}
|
||||
close(pidfile);
|
||||
}}'
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-autoipsetadder": {
|
||||
"description": "Grant UCI access for luci-app-autoipsetadder",
|
||||
"read": {
|
||||
"uci": [ "autoipsetadder" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "autoipsetadder" ]
|
||||
}
|
||||
}
|
||||
}
|
2
luci-app-beardropper/.gitattributes
vendored
Normal file
2
luci-app-beardropper/.gitattributes
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
2
luci-app-beardropper/.gitignore
vendored
Normal file
2
luci-app-beardropper/.gitignore
vendored
Normal file
@ -0,0 +1,2 @@
|
||||
|
||||
.DS_Store
|
622
luci-app-beardropper/LICENSE
Normal file
622
luci-app-beardropper/LICENSE
Normal file
@ -0,0 +1,622 @@
|
||||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
22
luci-app-beardropper/Makefile
Normal file
22
luci-app-beardropper/Makefile
Normal file
@ -0,0 +1,22 @@
|
||||
#
|
||||
# Copyright (C) 2020 Nate Ding
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v3.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_Title:=LuCI Support for BearDropper
|
||||
LUCI_PKGARCH=all
|
||||
|
||||
PKG_VERSION:=1.1
|
||||
PKG_RELEASE:=20200522
|
||||
|
||||
PKG_MAINTANINER:=Nate Ding <natelol@github.com>
|
||||
PKG_LICENSE:=GLPv3
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
59
luci-app-beardropper/README.md
Normal file
59
luci-app-beardropper/README.md
Normal file
@ -0,0 +1,59 @@
|
||||
luci-app-beardropper
|
||||
===
|
||||
|
||||
[Preview][preview]
|
||||
---
|
||||
luci-app-beardropper, a log examination script w/ iptables firewall rule generation response.
|
||||
|
||||
This is the LuCI app built for the elegant firewall rule generation on-the-fly script [bearDropper][bearDropper], only a few modifications were made to work with Luci.
|
||||
|
||||
|
||||
|
||||
Targets/Devices
|
||||
---
|
||||
Written in shell scripts, so it shall work all good on all devices.
|
||||
|
||||
|
||||
Config
|
||||
---
|
||||
The config file path is: `/etc/config/beardropper` and this is the uci configuration format.
|
||||
|
||||
|
||||
|
||||
Compile
|
||||
---
|
||||
RECOMMENDED!!!! (推荐使用右边的feeds---->)You can use [natelol feeds][feeds]
|
||||
|
||||
|
||||
OR
|
||||
|
||||
|
||||
0. Go under `openwrt/`
|
||||
|
||||
1. Make your own local feeds, say a folder `mkdir yourfeeds`
|
||||
|
||||
2. Clone master under feeds to have `git clone https://github.com/natelol/luci-app-beardropper yourefeeds/luci-app-beardropper`
|
||||
|
||||
3. Append `src-link yourfeeds /path/to/openwrt/yourfeeds` in the file `openwrt/feeds.conf(.default)`
|
||||
|
||||
4. Run following scripts under `openwrt`:
|
||||
|
||||
```bash
|
||||
# Update feeds
|
||||
./scripts/feeds update -a
|
||||
./scripts/feeds install -a
|
||||
|
||||
# M select luci-app-beardropper in LuCI -> 3. Applications also 2. Modules->Translations if you want translations together
|
||||
make menuconfig
|
||||
# compile
|
||||
make package/feeds/luci-app-beardropper/compile V=99
|
||||
```
|
||||
|
||||
Logs
|
||||
---
|
||||
`2020-05-21` Added a new tab listing the blocked IPs.
|
||||
|
||||
|
||||
[preview]: https://github.com/natelol/luci-app-beardropper/tree/master/preview
|
||||
[bearDropper]: https://github.com/robzr/bearDropper
|
||||
[feeds]: https://github.com/natelol/natelol
|
19
luci-app-beardropper/luasrc/controller/beardropper.lua
Executable file
19
luci-app-beardropper/luasrc/controller/beardropper.lua
Executable file
@ -0,0 +1,19 @@
|
||||
module("luci.controller.beardropper", package.seeall)
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/beardropper") then
|
||||
return
|
||||
end
|
||||
entry({"admin", "services", "beardropper"}, alias("admin", "services", "beardropper", "setting"),_("BearDropper"), 20).dependent = true
|
||||
entry({"admin", "services", "beardropper", "status"}, call("act_status"))
|
||||
entry({"admin", "services", "beardropper", "setting"}, cbi("beardropper/setting"), _("Setting"), 30).leaf= true
|
||||
entry({"admin", "services", "beardropper", "log"}, form("beardropper/log"),_("Log"),40).leaf= true
|
||||
--entry:
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.running = luci.sys.call("pgrep -f /usr/sbin/beardropper >/dev/null")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
17
luci-app-beardropper/luasrc/model/cbi/beardropper/log.lua
Normal file
17
luci-app-beardropper/luasrc/model/cbi/beardropper/log.lua
Normal file
@ -0,0 +1,17 @@
|
||||
f = SimpleForm("logview")
|
||||
f.reset = false
|
||||
f.submit = false
|
||||
t = f:field(TextValue, "conf")
|
||||
t.rmempty = true
|
||||
t.rows = 20
|
||||
function t.cfgvalue()
|
||||
local logs = luci.util.execi("logread | grep authpriv | grep beardropper")
|
||||
local s = ""
|
||||
for line in logs do
|
||||
s = line .. "\n" .. s
|
||||
end
|
||||
return s
|
||||
end
|
||||
t.readonly="readonly"
|
||||
|
||||
return f
|
54
luci-app-beardropper/luasrc/model/cbi/beardropper/setting.lua
Executable file
54
luci-app-beardropper/luasrc/model/cbi/beardropper/setting.lua
Executable file
@ -0,0 +1,54 @@
|
||||
|
||||
m = Map("beardropper", translate("BearDropper"),
|
||||
translate("luci-app-beardropper, the LuCI app built with the elegant firewall rule generation on-the-fly script bearDropper. <br /> <br /> Should you have any questions, please refer to the repo: ")..[[<a href="https://github.com/NateLol/luci-app-bearDropper" target="_blank">luci-app-beardropper</a>]]
|
||||
)
|
||||
m:chain("luci")
|
||||
|
||||
m:section(SimpleSection).template="beardropper/status"
|
||||
|
||||
s = m:section(TypedSection, "beardropper", translate(""))
|
||||
s.anonymous = true
|
||||
s.addremove = false
|
||||
|
||||
-- TABS
|
||||
s:tab("options", translate("Options"))
|
||||
s:tab("blocked", translate("Blocked IP"))
|
||||
|
||||
o = s:taboption("options", Flag, "enabled",translate("Enabled"))
|
||||
o.default = 0
|
||||
|
||||
-- OPTIONS
|
||||
o = s:taboption("options", ListValue, "defaultMode", translate("Running Mode"))
|
||||
o.default = "follow"
|
||||
o:value("follow", translate("Follow"))
|
||||
o:value("entire", translate("Entire"))
|
||||
o:value("today", translate("Today"))
|
||||
o:value("wipe", translate("Wipe"))
|
||||
|
||||
|
||||
o = s:taboption("options", Value, "attemptCount", translate("Attempt Tolerance"), translate("failure attempts from a given IP required to trigger a ban"))
|
||||
|
||||
o = s:taboption("options", Value, "attemptPeriod", translate("Attempt Cycle"), translate("time period during which attemptCount must be exceeded in order to trigger a ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"))
|
||||
|
||||
o = s:taboption("options", Value, "banLength", translate("Ban Period"), translate("how long a ban exist once the attempt threshold is exceeded"))
|
||||
|
||||
o = s:taboption("options", ListValue, "logLevel", translate("Log Level"))
|
||||
o.default = "1"
|
||||
o:value("0", translate("Silent"))
|
||||
o:value("1", translate("Default"))
|
||||
o:value("2", translate("Verbose"))
|
||||
o:value("3", translate("Debug"))
|
||||
|
||||
|
||||
o = s:taboption("blocked", Value, "blocked", translate("Blocked IP List"))
|
||||
o.template="cbi/tvalue"
|
||||
o.rows=40
|
||||
o.wrap="off"
|
||||
o.readonly="true"
|
||||
function o.cfgvalue(e, e)
|
||||
return luci.sys.exec("cat /tmp/beardropper.bddb | awk /'=1/'| awk -F '=' '{print $1}' | awk '{print substr($0,6)}' | awk 'gsub(/_/,\":\",$0)'")
|
||||
end
|
||||
|
||||
|
||||
|
||||
return m
|
22
luci-app-beardropper/luasrc/view/beardropper/status.htm
Executable file
22
luci-app-beardropper/luasrc/view/beardropper/status.htm
Executable file
@ -0,0 +1,22 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(3, '<%=url([[admin]], [[services]], [[beardropper]], [[status]])%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('beardropper_status');
|
||||
if (data && tb) {
|
||||
if (data.running) {
|
||||
var links = '<em><b><font color=green>BearDropper <%:RUNNING%></font></b></em>';
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><b><font color=red>BearDropper <%:NOT RUNNING%></font></b></em>';
|
||||
}
|
||||
}
|
||||
}
|
||||
);
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 50px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<p id="beardropper_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
115
luci-app-beardropper/po/zh_Hans/beardropper.po
Executable file
115
luci-app-beardropper/po/zh_Hans/beardropper.po
Executable file
@ -0,0 +1,115 @@
|
||||
bearDropper#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid "Attempt Cycle"
|
||||
msgstr "尝试登录时间段"
|
||||
|
||||
|
||||
msgid "Setting"
|
||||
msgstr "设置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日志"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "Attempt Tolerance"
|
||||
msgstr "最大尝试登录次数"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "Ban Period"
|
||||
msgstr "封禁IP时长"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/controller/bearDropper.lua:7
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:7
|
||||
msgid "BearDropper"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:20
|
||||
msgid "Blocked IP"
|
||||
msgstr "屏蔽列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:52
|
||||
msgid "Blocked IP List"
|
||||
msgstr "已屏蔽IP列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:45
|
||||
msgid "Debug"
|
||||
msgstr "调试"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:43
|
||||
msgid "Default"
|
||||
msgstr "默认"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:22
|
||||
msgid "Enabled"
|
||||
msgstr "启用"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:29
|
||||
msgid "Entire"
|
||||
msgstr "已有记录"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:28
|
||||
msgid "Follow"
|
||||
msgstr "后台监控"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:40
|
||||
msgid "Log Level"
|
||||
msgstr "日志等级"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:19
|
||||
msgid "Options"
|
||||
msgstr "选项"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:26
|
||||
msgid "Running Mode"
|
||||
msgstr "运行模式"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:42
|
||||
msgid "Silent"
|
||||
msgstr "安静"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:30
|
||||
msgid "Today"
|
||||
msgstr "仅今日"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:44
|
||||
msgid "Verbose"
|
||||
msgstr "详细"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:31
|
||||
msgid "Wipe"
|
||||
msgstr "清除所有"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "failure attempts from a given IP required to trigger a ban"
|
||||
msgstr "尝试登录超过设定值次数的IP将被封禁"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "how long a ban exist once the attempt threshold is exceeded"
|
||||
msgstr "IP将被封禁设定的时间"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:8
|
||||
msgid ""
|
||||
"luci-app-beardropper, the LuCI app built with the elegant firewall rule "
|
||||
"generation on-the-fly script bearDropper. <br /> <br /> Should you have any "
|
||||
"questions, please refer to the repo:"
|
||||
msgstr ""
|
||||
"luci-app-beardropper, 是一款能够在开启公网访问之后对潜在的ssh attack进行防御"
|
||||
"的脚本. <br /> <br /> 如果你在使用中有任何问题,请到项目中提问: "
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid ""
|
||||
"time period during which attemptCount must be exceeded in order to trigger a "
|
||||
"ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"
|
||||
msgstr ""
|
||||
"在设定的时间段内连续尝试失败 <br> 格式:1w2d3h4m5s代表1周2天3小时4分5秒"
|
115
luci-app-beardropper/po/zh_Hant/beardropper.po
Normal file
115
luci-app-beardropper/po/zh_Hant/beardropper.po
Normal file
@ -0,0 +1,115 @@
|
||||
bearDropper#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid "Attempt Cycle"
|
||||
msgstr "嘗試登錄時間段"
|
||||
|
||||
|
||||
msgid "Setting"
|
||||
msgstr "設置"
|
||||
|
||||
msgid "Log"
|
||||
msgstr "日誌"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "Attempt Tolerance"
|
||||
msgstr "最大嘗試登錄次數"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "Ban Period"
|
||||
msgstr "封禁IP時長"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/controller/bearDropper.lua:7
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:7
|
||||
msgid "BearDropper"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:20
|
||||
msgid "Blocked IP"
|
||||
msgstr "屏蔽列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:52
|
||||
msgid "Blocked IP List"
|
||||
msgstr "已屏蔽IP列表"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:20
|
||||
msgid "Collecting data..."
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:45
|
||||
msgid "Debug"
|
||||
msgstr "調試"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:43
|
||||
msgid "Default"
|
||||
msgstr "默認"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:22
|
||||
msgid "Enabled"
|
||||
msgstr "啟用"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:29
|
||||
msgid "Entire"
|
||||
msgstr "已有記錄"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:28
|
||||
msgid "Follow"
|
||||
msgstr "後臺監控"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:40
|
||||
msgid "Log Level"
|
||||
msgstr "日誌等級"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:10
|
||||
msgid "NOT RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:19
|
||||
msgid "Options"
|
||||
msgstr "選項"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/view/bearDropper/status.htm:7
|
||||
msgid "RUNNING"
|
||||
msgstr ""
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:26
|
||||
msgid "Running Mode"
|
||||
msgstr "運行模式"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:42
|
||||
msgid "Silent"
|
||||
msgstr "安靜"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:30
|
||||
msgid "Today"
|
||||
msgstr "僅今日"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:44
|
||||
msgid "Verbose"
|
||||
msgstr "詳細"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:31
|
||||
msgid "Wipe"
|
||||
msgstr "清除所有"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:34
|
||||
msgid "failure attempts from a given IP required to trigger a ban"
|
||||
msgstr "嘗試登錄超過設定值次數的IP將被封禁"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:38
|
||||
msgid "how long a ban exist once the attempt threshold is exceeded"
|
||||
msgstr "IP將被封禁設定的時間"
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:8
|
||||
msgid ""
|
||||
"luci-app-beardropper, the LuCI app built with the elegant firewall rule "
|
||||
"generation on-the-fly script bearDropper. <br /> <br /> Should you have any "
|
||||
"questions, please refer to the repo:"
|
||||
msgstr ""
|
||||
"luci-app-beardropper, 是壹款能夠在開啟公網訪問之後對潛在的ssh attack進行防禦"
|
||||
"的腳本. <br /> <br /> 如果妳在使用中有任何問題,請到項目中提問: "
|
||||
|
||||
#: ../../package/feeds/luci/luci-app-beardropper/luasrc/model/cbi/bearDropper/setting.lua:36
|
||||
msgid ""
|
||||
"time period during which attemptCount must be exceeded in order to trigger a "
|
||||
"ban <br> Format: 1w2d3h4m5s represents 1week 2days 3hours 4minutes 5 seconds"
|
||||
msgstr ""
|
||||
"在設定的時間段內連續嘗試失敗 <br> 格式:1w2d3h4m5s代表1周2天3小時4分5秒"
|
BIN
luci-app-beardropper/preview/1_setting.png
Normal file
BIN
luci-app-beardropper/preview/1_setting.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 111 KiB |
BIN
luci-app-beardropper/preview/2_blockedlist.png
Normal file
BIN
luci-app-beardropper/preview/2_blockedlist.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 124 KiB |
18
luci-app-beardropper/root/etc/config/beardropper
Normal file
18
luci-app-beardropper/root/etc/config/beardropper
Normal file
@ -0,0 +1,18 @@
|
||||
config beardropper
|
||||
option attemptCount '5'
|
||||
option attemptPeriod '12h'
|
||||
option banLength '1w'
|
||||
option logFacility 'authpriv.notice'
|
||||
option fileStateType 'bddb'
|
||||
option fileStateTempPrefix '/tmp/beardropper'
|
||||
option fileStatePersistPrefix '/etc/beardropper'
|
||||
list firewallHookChain 'input_wan_rule:1'
|
||||
list firewallHookChain 'forwarding_wan_rule:1'
|
||||
option firewallTarget 'DROP'
|
||||
list logRegex 's/[`$"\'\'']//g'
|
||||
list logRegex '/has invalid shell, rejected$/d'
|
||||
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p'
|
||||
list logRegex '/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p'
|
||||
option defaultMode 'follow'
|
||||
option enabled '1'
|
||||
option logLevel '2'
|
46
luci-app-beardropper/root/etc/init.d/beardropper
Executable file
46
luci-app-beardropper/root/etc/init.d/beardropper
Executable file
@ -0,0 +1,46 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
START=98
|
||||
|
||||
PROG=/usr/sbin/beardropper
|
||||
SERVICE_DAEMONIZE=1
|
||||
SERVICE_WRITE_PID=1
|
||||
|
||||
getKids() {
|
||||
egrep "^PPid: *$1$" /proc/[0-9]*/s*s 2>/dev/null | cut -f3 -d/ | xargs echo
|
||||
}
|
||||
|
||||
start() {
|
||||
service_start ${PROG} -m follow
|
||||
echo "beardropper started!"
|
||||
}
|
||||
|
||||
stop() {
|
||||
#PID=`cat /var/run/bearDropper.pid`
|
||||
#kill `getKids $PID`
|
||||
kill -9 `pgrep -f /usr/sbin/beardropper`
|
||||
sleep 1
|
||||
service_stop ${PROG}
|
||||
echo "beardropper exit...."
|
||||
}
|
||||
|
||||
restart() {
|
||||
enabled=$(uci get beardropper.@beardropper[0].enabled)
|
||||
pgrep -f ${PROG} >/dev/null
|
||||
if [ $? -eq 0 ];then #running
|
||||
if [ $enabled -eq 1 ]; then
|
||||
stop
|
||||
sleep 1
|
||||
echo "beardropper is restarting..."
|
||||
start
|
||||
else
|
||||
stop
|
||||
fi
|
||||
else
|
||||
if [ $enabled -eq 1 ]; then
|
||||
start
|
||||
else
|
||||
exit 0
|
||||
fi
|
||||
fi
|
||||
|
||||
}
|
11
luci-app-beardropper/root/etc/uci-defaults/luci-beardropper
Normal file
11
luci-app-beardropper/root/etc/uci-defaults/luci-beardropper
Normal file
@ -0,0 +1,11 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@beardropper[-1]
|
||||
add ucitrack beardropper
|
||||
set ucitrack.@beardropper[-1].init=beardropper
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
rm -rf /tmp/luci-*
|
||||
exit 0
|
517
luci-app-beardropper/root/usr/sbin/beardropper
Executable file
517
luci-app-beardropper/root/usr/sbin/beardropper
Executable file
@ -0,0 +1,517 @@
|
||||
#!/bin/ash
|
||||
#
|
||||
# beardropper - dropbear log parsing ban agent for OpenWRT (Chaos Calmer rewrite of dropBrute.sh)
|
||||
# http://github.com/robzr/bearDropper -- Rob Zwissler 11/2015
|
||||
#
|
||||
# - lightweight, no dependencies, busybox ash + native OpenWRT commands
|
||||
# - uses uci for configuration, overrideable via command line arguments
|
||||
# - runs continuously in background (via init script) or periodically (via cron)
|
||||
# - uses BIND time shorthand, ex: 1w5d3h1m8s is 1 week, 5 days, 3 hours, 1 minute, 8 seconds
|
||||
# - Whitelist IP or CIDR entries (TBD) in uci config file
|
||||
# - Records state file to tmpfs and intelligently syncs to persistent storage (can disable)
|
||||
# - Persistent sync routines are optimized to avoid excessive writes (persistentStateWritePeriod)
|
||||
# - Every run occurs in one of the following modes. If not specified, interval mode (24 hours) is
|
||||
# the default when not specified (the init script specifies follow mode via command line)
|
||||
#
|
||||
# "follow" mode follows syslog to process entries as they happen; generally launched via init
|
||||
# script. Responds the fastest, runs the most efficiently, but is always in memory.
|
||||
# "interval" mode only processes entries going back the specified interval; requires
|
||||
# more processing than today mode, but responds more accurately. Use with cron.
|
||||
# "today" mode looks at log entries from the day it is being run, simple and lightweight,
|
||||
# generally run from cron periodically (same simplistic behavior as dropBrute.sh)
|
||||
# "entire" mode runs through entire contents of the syslog ring buffer
|
||||
# "wipe" mode tears down the firewall rules and removes the state files
|
||||
|
||||
# Load UCI config variable, or use default if not set
|
||||
# Args: $1 = variable name (also uci option name), $2 = default_value
|
||||
uciSection='beardropper.@[0]'
|
||||
uciLoadVar () {
|
||||
local getUci
|
||||
getUci=`uci -q get ${uciSection}."$1"` || getUci="$2"
|
||||
eval $1=\'$getUci\';
|
||||
}
|
||||
uciLoad() {
|
||||
local tFile=`mktemp` delim="
|
||||
"
|
||||
[ "$1" = -d ] && { delim="$2"; shift 2; }
|
||||
uci -q -d"$delim" get "$uciSection.$1" 2>/dev/null >$tFile
|
||||
if [ $? = 0 ] ; then
|
||||
sed -e s/^\'// -e s/\'$// <$tFile
|
||||
else
|
||||
while [ -n "$2" ]; do echo $2; shift; done
|
||||
fi
|
||||
rm -f $tFile
|
||||
}
|
||||
|
||||
# Common config variables - edit these in /etc/config/beardropper
|
||||
# or they can be overridden at runtime with command line options
|
||||
#
|
||||
uciLoadVar defaultMode entire
|
||||
uciLoadVar enabled 0
|
||||
uciLoadVar attemptCount 10
|
||||
uciLoadVar attemptPeriod 12h
|
||||
uciLoadVar banLength 1w
|
||||
uciLoadVar logLevel 1
|
||||
uciLoadVar logFacility authpriv.notice
|
||||
uciLoadVar persistentStateWritePeriod -1
|
||||
uciLoadVar fileStateType bddb
|
||||
uciLoadVar fileStateTempPrefix /tmp/beardropper
|
||||
uciLoadVar fileStatePersistPrefix /etc/beardropper
|
||||
firewallHookChains="`uciLoad -d \ firewallHookChain input_wan_rule:1 forwarding_wan_rule:1`"
|
||||
uciLoadVar firewallTarget DROP
|
||||
|
||||
# Not commonly changed, but changeable via uci or cmdline (primarily
|
||||
# to enable multiple parallel runs with different parameters)
|
||||
uciLoadVar firewallChain beardropper
|
||||
|
||||
# Advanced variables, changeable via uci only (no cmdline), it is
|
||||
# unlikely that these will need to be changed, but just in case...
|
||||
#
|
||||
uciLoadVar syslogTag "beardropper[$$]"
|
||||
# how often to attempt to expire bans when in follow mode
|
||||
uciLoadVar followModeCheckInterval 30m
|
||||
uciLoadVar cmdLogread 'logread' # for tuning, ex: "logread -l250"
|
||||
uciLoadVar cmdLogreadEba 'logread' # for "Exit before auth:" backscanning
|
||||
uciLoadVar formatLogDate '%b %e %H:%M:%S %Y' # used to convert syslog dates
|
||||
uciLoadVar formatTodayLogDateRegex '^%a %b %e ..:..:.. %Y' # filter for today mode
|
||||
|
||||
# Begin functions
|
||||
#
|
||||
# Clear bddb entries from environment
|
||||
bddbClear () {
|
||||
local bddbVar
|
||||
for bddbVar in `set | egrep '^bddb_[0-9_]*=' | cut -f1 -d= | xargs echo -n` ; do eval unset $bddbVar ; done
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Returns count of unique IP entries in environment
|
||||
bddbCount () { set | egrep '^bddb_[0-9_]*=' | wc -l ; }
|
||||
|
||||
# Loads existing bddb file into environment
|
||||
# Arg: $1 = file, $2 = type (bddb/bddbz), $3 =
|
||||
bddbLoad () {
|
||||
local loadFile="$1.$2" fileType="$2"
|
||||
if [ "$fileType" = bddb -a -f "$loadFile" ] ; then
|
||||
. "$loadFile"
|
||||
elif [ "$fileType" = bddbz -a -f "$loadFile" ] ; then
|
||||
local tmpFile="`mktemp`"
|
||||
zcat $loadFile > "$tmpFile"
|
||||
. "$tmpFile"
|
||||
rm -f "$tmpFile"
|
||||
fi
|
||||
bddbStateChange=0
|
||||
}
|
||||
|
||||
# Saves environment bddb entries to file, Arg: $1 = file to save in
|
||||
bddbSave () {
|
||||
local saveFile="$1.$2" fileType="$2"
|
||||
if [ "$fileType" = bddb ] ; then
|
||||
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g > "$saveFile"
|
||||
elif [ "$fileType" = bddbz ] ; then
|
||||
set | egrep '^bddb_[0-9_]*=' | sed s/\'//g | gzip -c > "$saveFile"
|
||||
fi
|
||||
bddbStateChange=0
|
||||
}
|
||||
|
||||
# Set bddb record status=1, update ban time flag with newest
|
||||
# Args: $1=IP Address $2=timeFlag
|
||||
bddbEnableStatus () {
|
||||
local record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
|
||||
local newestTime=`bddbGetTimes $1 | sed 's/.* //' | xargs echo $2 | tr \ '\n' | sort -n | tail -1 `
|
||||
eval $record="1,$newestTime"
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Args: $1=IP Address
|
||||
bddbGetStatus () {
|
||||
bddbGetRecord $1 | cut -d, -f1
|
||||
}
|
||||
|
||||
# Args: $1=IP Address
|
||||
bddbGetTimes () {
|
||||
bddbGetRecord $1 | cut -d, -f2-
|
||||
}
|
||||
|
||||
# Args: $1 = IP address, $2 [$3 ...] = timestamp (seconds since epoch)
|
||||
bddbAddRecord () {
|
||||
local ip="`echo "$1" | tr . _`" ; shift
|
||||
local newEpochList="$@" status="`eval echo \\\$bddb_$ip | cut -f1 -d,`"
|
||||
local oldEpochList="`eval echo \\\$bddb_$ip | cut -f2- -d, | tr , \ `"
|
||||
local epochList=`echo $oldEpochList $newEpochList | xargs -n 1 echo | sort -un | xargs echo -n | tr \ ,`
|
||||
[ -z "$status" ] && status=0
|
||||
eval "bddb_$ip"\=\"$status,$epochList\"
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Args: $1 = IP address
|
||||
bddbRemoveRecord () {
|
||||
local ip="`echo "$1" | tr . _`"
|
||||
eval unset bddb_$ip
|
||||
bddbStateChange=1
|
||||
}
|
||||
|
||||
# Returns all IPs (not CIDR) present in records
|
||||
bddbGetAllIPs () {
|
||||
local ipRaw record
|
||||
set | egrep '^bddb_[0-9_]*=' | tr \' \ | while read record ; do
|
||||
ipRaw=`echo $record | cut -f1 -d= | sed 's/^bddb_//'`
|
||||
if [ `echo $ipRaw | tr _ \ | wc -w` -eq 4 ] ; then
|
||||
echo $ipRaw | tr _ .
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
# retrieve single IP record, Args: $1=IP
|
||||
bddbGetRecord () {
|
||||
local record
|
||||
record=`echo $1 | sed -e 's/\./_/g' -e 's/^/bddb_/'`
|
||||
eval echo \$$record
|
||||
}
|
||||
|
||||
isValidBindTime () { echo "$1" | egrep -q '^[0-9]+$|^([0-9]+[wdhms]?)+$' ; }
|
||||
|
||||
# expands Bind time syntax into seconds (ex: 3w6d23h59m59s), Arg: $1=time string
|
||||
expandBindTime () {
|
||||
isValidBindTime "$1" || { logLine 0 "Error: Invalid time specified ($1)" >&2 ; exit 254 ; }
|
||||
echo $((`echo "$1" | sed -e 's/w+*/*7d+/g' -e 's/d+*/*24h+/g' -e 's/h+*/*60m+/g' -e 's/m+*/*60+/g' \
|
||||
-e s/s//g -e s/+\$//`))
|
||||
}
|
||||
|
||||
# Args: $1 = loglevel, $2 = info to log
|
||||
logLine () {
|
||||
[ $1 -gt $logLevel ] && return
|
||||
shift
|
||||
if [ "$logFacility" = "stdout" ] ; then echo "$@"
|
||||
elif [ "$logFacility" = "stderr" ] ; then echo "$@" >&2
|
||||
else logger -t "$syslogTag" -p "$logFacility" "$@"
|
||||
fi
|
||||
}
|
||||
|
||||
# extra validation, fails safe. Args: $1=log line
|
||||
getLogTime () {
|
||||
local logDateString=`echo "$1" | sed -n \
|
||||
's/^[A-Z][a-z]* \([A-Z][a-z]* *[0-9][0-9]* *[0-9][0-9]*:[0-9][0-9]:[0-9][0-9] [0-9][0-9]*\) .*$/\1/p'`
|
||||
date -d"$logDateString" -D"$formatLogDate" +%s || logLine 1 \
|
||||
"Error: logDateString($logDateString) malformed line ($1)"
|
||||
}
|
||||
|
||||
# extra validation, fails safe. Args: $1=log line
|
||||
getLogIP () {
|
||||
local logLine="$1"
|
||||
local ebaPID=`echo "$logLine" | sed -n 's/^.*authpriv.info \(dropbear\[[0-9]*\]:\) Exit before auth:.*/\1/p'`
|
||||
[ -n "$ebaPID" ] && logLine=`$cmdLogreadEba | fgrep "${ebaPID} Child connection from "`
|
||||
echo "$logLine" | sed -n 's/^.*[^0-9]\([0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\.[0-9][0-9]*\).*$/\1/p'
|
||||
}
|
||||
|
||||
# Args: $1=IP
|
||||
unBanIP () {
|
||||
if iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
|
||||
logLine 1 "Removing ban rule for IP $ip from iptables"
|
||||
iptables -D $firewallChain -s $ip -j "$firewallTarget"
|
||||
else
|
||||
logLine 3 "unBanIP() Ban rule for $ip not present in iptables"
|
||||
fi
|
||||
}
|
||||
|
||||
# Args: $1=IP
|
||||
banIP () {
|
||||
local ip="$1" x chain position
|
||||
if ! iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
|
||||
logLine 1 "Creating iptables chain $firewallChain"
|
||||
iptables -N $firewallChain
|
||||
fi
|
||||
for x in $firewallHookChains ; do
|
||||
chain="${x%:*}" ; position="${x#*:}"
|
||||
if [ $position -ge 0 ] && ! iptables -C $chain -j $firewallChain 2>/dev/null ; then
|
||||
logLine 1 "Inserting hook into iptables chain $chain"
|
||||
if [ $position = 0 ] ; then
|
||||
iptables -A $chain -j $firewallChain
|
||||
else
|
||||
iptables -I $chain $position -j $firewallChain
|
||||
fi ; fi
|
||||
done
|
||||
if ! iptables -C $firewallChain -s $ip -j "$firewallTarget" 2>/dev/null ; then
|
||||
logLine 1 "Inserting ban rule for IP $ip into iptables chain $firewallChain"
|
||||
iptables -A $firewallChain -s $ip -j "$firewallTarget"
|
||||
else
|
||||
logLine 3 "banIP() rule for $ip already present in iptables chain"
|
||||
fi
|
||||
}
|
||||
|
||||
wipeFirewall () {
|
||||
local x chain position
|
||||
for x in $firewallHookChains ; do
|
||||
chain="${x%:*}" ; position="${x#*:}"
|
||||
if [ $position -ge 0 ] ; then
|
||||
if iptables -C $chain -j $firewallChain 2>/dev/null ; then
|
||||
logLine 1 "Removing hook from iptables chain $chain"
|
||||
iptables -D $chain -j $firewallChain
|
||||
fi ; fi
|
||||
done
|
||||
if iptables -nL $firewallChain >/dev/null 2>/dev/null ; then
|
||||
logLine 1 "Flushing and removing iptables chain $firewallChain"
|
||||
iptables -F $firewallChain 2>/dev/null
|
||||
iptables -X $firewallChain 2>/dev/null
|
||||
fi
|
||||
}
|
||||
|
||||
# review state file for expired records - we could add the bantime to
|
||||
# the rule via --comment but I can't think of a reason why that would
|
||||
# be necessary unless there is a bug in the expiration logic. The
|
||||
# state db should be more resiliant than the firewall in practice.
|
||||
#
|
||||
bddbCheckStatusAll () {
|
||||
local now=`date +%s`
|
||||
bddbGetAllIPs | while read ip ; do
|
||||
if [ `bddbGetStatus $ip` -eq 1 ] ; then
|
||||
logLine 3 "bddbCheckStatusAll($ip) testing banLength:$banLength + bddbGetTimes:`bddbGetTimes $ip` vs. now:$now"
|
||||
if [ $((banLength + `bddbGetTimes $ip`)) -lt $now ] ; then
|
||||
logLine 1 "Ban expired for $ip, removing from iptables"
|
||||
unBanIP $ip
|
||||
bddbRemoveRecord $ip
|
||||
else
|
||||
logLine 3 "bddbCheckStatusAll($ip) not expired yet"
|
||||
banIP $ip
|
||||
fi
|
||||
elif [ `bddbGetStatus $ip` -eq 0 ] ; then
|
||||
local times=`bddbGetTimes $ip | tr , \ `
|
||||
local timeCount=`echo $times | wc -w`
|
||||
local lastTime=`echo $times | cut -d\ -f$timeCount`
|
||||
if [ $((lastTime + attemptPeriod)) -lt $now ] ; then
|
||||
bddbRemoveRecord $ip
|
||||
fi ; fi
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
}
|
||||
|
||||
# Only used when status is already 0 and possibly going to 1, Args: $1=IP
|
||||
bddbEvaluateRecord () {
|
||||
local ip=$1 firstTime lastTime
|
||||
local times=`bddbGetRecord $1 | cut -d, -f2- | tr , \ `
|
||||
local timeCount=`echo $times | wc -w`
|
||||
local didBan=0
|
||||
|
||||
# 1: not enough attempts => do nothing and exit
|
||||
# 2: attempts exceed threshold in time period => ban
|
||||
# 3: attempts exceed threshold but time period is too long => trim oldest time, recalculate
|
||||
while [ $timeCount -ge $attemptCount ] ; do
|
||||
firstTime=`echo $times | cut -d\ -f1`
|
||||
lastTime=`echo $times | cut -d\ -f$timeCount`
|
||||
timeDiff=$((lastTime - firstTime))
|
||||
logLine 3 "bddbEvaluateRecord($ip) count=$timeCount timeDiff=$timeDiff/$attemptPeriod"
|
||||
if [ $timeDiff -le $attemptPeriod ] ; then
|
||||
bddbEnableStatus $ip $lastTime
|
||||
logLine 2 "bddbEvaluateRecord($ip) exceeded ban threshold, adding to iptables"
|
||||
banIP $ip
|
||||
didBan=1
|
||||
fi
|
||||
times=`echo $times | cut -d\ -f2-`
|
||||
timeCount=`echo $times | wc -w`
|
||||
done
|
||||
[ $didBan = 0 ] && logLine 2 "bddbEvaluateRecord($ip) does not exceed threshhold, skipping"
|
||||
}
|
||||
|
||||
# Reads filtered log line and evaluates for action Args: $1=log line
|
||||
processLogLine () {
|
||||
local time=`getLogTime "$1"`
|
||||
local ip=`getLogIP "$1"`
|
||||
local status="`bddbGetStatus $ip`"
|
||||
|
||||
if [ "$status" = -1 ] ; then
|
||||
logLine 2 "processLogLine($ip,$time) IP is whitelisted"
|
||||
elif [ "$status" = 1 ] ; then
|
||||
if [ "`bddbGetTimes $ip`" -ge $time ] ; then
|
||||
logLine 2 "processLogLine($ip,$time) already banned, ban timestamp already equal or newer"
|
||||
else
|
||||
logLine 2 "processLogLine($ip,$time) already banned, updating ban timestamp"
|
||||
bddbEnableStatus $ip $time
|
||||
fi
|
||||
banIP $ip
|
||||
elif [ -n "$ip" -a -n "$time" ] ; then
|
||||
bddbAddRecord $ip $time
|
||||
logLine 2 "processLogLine($ip,$time) Added record, comparing"
|
||||
bddbEvaluateRecord $ip
|
||||
else
|
||||
logLine 1 "processLogLine($ip,$time) malformed line ($1)"
|
||||
fi
|
||||
}
|
||||
|
||||
# Args, $1=-f to force a persistent write (unless lastPersistentStateWrite=-1)
|
||||
saveState () {
|
||||
local forcePersistent=0
|
||||
[ "$1" = "-f" ] && forcePersistent=1
|
||||
|
||||
if [ $bddbStateChange -gt 0 ] ; then
|
||||
logLine 3 "saveState() saving to temp state file"
|
||||
bddbSave "$fileStateTempPrefix" "$fileStateType"
|
||||
logLine 3 "saveState() now=`date +%s` lPSW=$lastPersistentStateWrite pSWP=$persistentStateWritePeriod fP=$forcePersistent"
|
||||
fi
|
||||
if [ $persistentStateWritePeriod -gt 1 ] || [ $persistentStateWritePeriod -eq 0 -a $forcePersistent -eq 1 ] ; then
|
||||
if [ $((`date +%s` - lastPersistentStateWrite)) -ge $persistentStateWritePeriod ] || [ $forcePersistent -eq 1 ] ; then
|
||||
if [ ! -f "$fileStatePersist" ] || ! cmp -s "$fileStateTemp" "$fileStatePersist" ; then
|
||||
logLine 2 "saveState() writing to persistent state file"
|
||||
bddbSave "$fileStatePersistPrefix" "$fileStateType"
|
||||
lastPersistentStateWrite="`date +%s`"
|
||||
fi ; fi ; fi
|
||||
}
|
||||
|
||||
loadState () {
|
||||
bddbClear
|
||||
bddbLoad "$fileStatePersistPrefix" "$fileStateType"
|
||||
bddbLoad "$fileStateTempPrefix" "$fileStateType"
|
||||
logLine 2 "loadState() loaded `bddbCount` entries"
|
||||
}
|
||||
|
||||
printUsage () {
|
||||
cat <<-_EOF_
|
||||
Usage: beardropper [-m mode] [-a #] [-b #] [-c ...] [-C ...] [-f ...] [-l #] [-j ...] [-p #] [-P #] [-s ...]
|
||||
|
||||
Running Modes (-m) (def: $defaultMode)
|
||||
follow constantly monitors log
|
||||
entire processes entire log contents
|
||||
today processes log entries from same day only
|
||||
# interval mode, specify time string or seconds
|
||||
wipe wipe state files, unhook and remove firewall chain
|
||||
|
||||
Options
|
||||
-a # attempt count before banning (def: $attemptCount)
|
||||
-b # ban length once attempts hit threshold (def: $banLength)
|
||||
-c ... firewall chain to record bans (def: $firewallChain)
|
||||
-C ... firewall chains/positions to hook into (def: $firewallHookChains)
|
||||
-f ... log facility (syslog facility or stdout/stderr) (def: $logFacility)
|
||||
-j ... firewall target (def: $firewallTarget)
|
||||
-l # log level - 0=off, 1=standard, 2=verbose (def: $logLevel)
|
||||
-p # attempt period which attempt counts must happen in (def: $attemptPeriod)
|
||||
-P # persistent state file write period (def: $persistentStateWritePeriod)
|
||||
-s ... persistent state file prefix (def: $fileStatePersistPrefix)
|
||||
-t ... temporary state file prefix (def: $fileStateTempPrefix)
|
||||
|
||||
All time strings can be specified in seconds, or using BIND style
|
||||
time strings, ex: 1w2d3h5m30s is 1 week, 2 days, 3 hours, etc...
|
||||
|
||||
_EOF_
|
||||
}
|
||||
|
||||
# Begin main logic
|
||||
#
|
||||
unset logMode
|
||||
while getopts a:b:c:C:f:hj:l:m:p:P:s:t: arg ; do
|
||||
case "$arg" in
|
||||
a) attemptCount="$OPTARG" ;;
|
||||
b) banLength="$OPTARG" ;;
|
||||
c) firewallChain="$OPTARG" ;;
|
||||
C) firewallHookChains="$OPTARG" ;;
|
||||
f) logFacility="$OPTARG" ;;
|
||||
j) firewallTarget="$OPTARG" ;;
|
||||
l) logLevel="$OPTARG" ;;
|
||||
m) logMode="$OPTARG" ;;
|
||||
p) attemptPeriod="$OPTARG" ;;
|
||||
P) persistentStateWritePeriod="$OPTARG" ;;
|
||||
s) fileStatePersistPrefix="$OPTARG" ;;
|
||||
s) fileStatePersistPrefix="$OPTARG" ;;
|
||||
*) printUsage
|
||||
exit 254
|
||||
esac
|
||||
shift `expr $OPTIND - 1`
|
||||
done
|
||||
[ -z $logMode ] && logMode="$defaultMode"
|
||||
|
||||
fileStateTemp="$fileStateTempPrefix.$fileStateType"
|
||||
fileStatePersist="$fileStatePersistPrefix.$fileStateType"
|
||||
|
||||
attemptPeriod=`expandBindTime $attemptPeriod`
|
||||
banLength=`expandBindTime $banLength`
|
||||
[ $persistentStateWritePeriod != -1 ] && persistentStateWritePeriod=`expandBindTime $persistentStateWritePeriod`
|
||||
followModeCheckInterval=`expandBindTime $followModeCheckInterval`
|
||||
exitStatus=0
|
||||
|
||||
# Here we convert the logRegex list into a sed -f file
|
||||
fileRegex="/tmp/beardropper.$$.regex"
|
||||
uciLoad logRegex 's/[`$"'\\\'']//g' '/has invalid shell, rejected$/d' \
|
||||
'/^[A-Za-z ]+[0-9: ]+authpriv.warn dropbear\[.+([0-9]+\.){3}[0-9]+/p' \
|
||||
'/^[A-Za-z ]+[0-9: ]+authpriv.info dropbear\[.+:\ Exit before auth:.*/p' > "$fileRegex"
|
||||
lastPersistentStateWrite="`date +%s`"
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
|
||||
# main event loops
|
||||
|
||||
if [ "$logMode" = follow ] ; then
|
||||
logLine 1 "Running in follow mode"
|
||||
readsSinceSave=0 lastCheckAll=0 worstCaseReads=1 tmpFile="/tmp/beardropper.$$.1"
|
||||
# Verify if these do any good - try saving to a temp. Scope may make saveState useless.
|
||||
trap "rm -f "$tmpFile" "$fileRegex" ; exit " SIGINT
|
||||
[ $persistentStateWritePeriod -gt 1 ] && worstCaseReads=$((persistentStateWritePeriod / followModeCheckInterval))
|
||||
firstRun=1
|
||||
$cmdLogread -f | while read -t $followModeCheckInterval line || true ; do
|
||||
if [ $firstRun -eq 1 ] ; then
|
||||
trap "saveState -f" SIGHUP
|
||||
trap "saveState -f; exit" SIGINT
|
||||
firstRun=0
|
||||
fi
|
||||
sed -nEf "$fileRegex" > "$tmpFile" <<-_EOF_
|
||||
$line
|
||||
_EOF_
|
||||
line="`cat $tmpFile`"
|
||||
[ -n "$line" ] && processLogLine "$line"
|
||||
logLine 3 "ReadComp:$readsSinceSave/$worstCaseReads"
|
||||
if [ $((++readsSinceSave)) -ge $worstCaseReads ] ; then
|
||||
now="`date +%s`"
|
||||
if [ $((now - lastCheckAll)) -ge $followModeCheckInterval ] ; then
|
||||
bddbCheckStatusAll
|
||||
lastCheckAll="$now"
|
||||
saveState
|
||||
readsSinceSave=0
|
||||
fi
|
||||
fi
|
||||
done
|
||||
elif [ "$logMode" = entire ] ; then
|
||||
logLine 1 "Running in entire mode"
|
||||
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
|
||||
processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif [ "$logMode" = today ] ; then
|
||||
logLine 1 "Running in today mode"
|
||||
# merge the egrep into sed with -e /^$formatTodayLogDateRegex/!d
|
||||
$cmdLogread | egrep "`date +\'$formatTodayLogDateRegex\'`" | sed -nEf "$fileRegex" | while read line ; do
|
||||
processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif isValidBindTime "$logMode" ; then
|
||||
logInterval=`expandBindTime $logMode`
|
||||
logLine 1 "Running in interval mode (reviewing $logInterval seconds of log entries)..."
|
||||
timeStart=$((`date +%s` - logInterval))
|
||||
$cmdLogread | sed -nEf "$fileRegex" | while read line ; do
|
||||
timeWhen=`getLogTime "$line"`
|
||||
[ $timeWhen -ge $timeStart ] && processLogLine "$line"
|
||||
saveState
|
||||
done
|
||||
loadState
|
||||
bddbCheckStatusAll
|
||||
saveState -f
|
||||
elif [ "$logMode" = wipe ] ; then
|
||||
logLine 2 "Wiping state files, unhooking and removing iptables chains"
|
||||
wipeFirewall
|
||||
if [ -f "$fileStateTemp" ] ; then
|
||||
logLine 1 "Removing non-persistent statefile ($fileStateTemp)"
|
||||
rm -f "$fileStateTemp"
|
||||
fi
|
||||
if [ -f "$fileStatePersist" ] ; then
|
||||
logLine 1 "Removing persistent statefile ($fileStatePersist)"
|
||||
rm -f "$fileStatePersist"
|
||||
fi
|
||||
else
|
||||
logLine 0 "Error: invalid log mode ($logMode)"
|
||||
exitStatus=254
|
||||
fi
|
||||
|
||||
rm -f "$fileRegex"
|
||||
exit $exitStatus
|
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-beardropper": {
|
||||
"description": "Grant UCI access for luci-app-beardropper",
|
||||
"read": {
|
||||
"uci": [ "beardropper" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "beardropper" ]
|
||||
}
|
||||
}
|
||||
}
|
76
luci-app-godproxy/Makefile
Normal file
76
luci-app-godproxy/Makefile
Normal file
@ -0,0 +1,76 @@
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=luci-app-godproxy
|
||||
PKG_VERSION:=3.8.5
|
||||
PKG_RELEASE:=3-20210323
|
||||
|
||||
PKG_MAINTAINER:=panda-mute <wxuzju@gmail.com>
|
||||
PKG_LICENSE:=GPLv3
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
RSTRIP:=true
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/luci-app-godproxy
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
SUBMENU:=3. Applications
|
||||
TITLE:=LuCI support for koolproxy
|
||||
DEPENDS:=+openssl-util +ipset +dnsmasq-full +@BUSYBOX_CONFIG_DIFF +iptables-mod-nat-extra +wget
|
||||
MAINTAINER:=panda-mute
|
||||
endef
|
||||
|
||||
define Package/luci-app-godproxy/description
|
||||
This package contains LuCI configuration pages for koolproxy.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/luci-app-godproxy/postinst
|
||||
#!/bin/sh
|
||||
if [ -z "$${IPKG_INSTROOT}" ]; then
|
||||
( . /etc/uci-defaults/luci-koolproxy ) && rm -f /etc/uci-defaults/luci-koolproxy
|
||||
rm -f /tmp/luci-indexcache
|
||||
fi
|
||||
exit 0
|
||||
endef
|
||||
|
||||
define Package/luci-app-godproxy/conffiles
|
||||
/etc/config/koolproxy
|
||||
/usr/share/koolproxy/data/rules/
|
||||
endef
|
||||
|
||||
|
||||
define Package/luci-app-godproxy/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci
|
||||
cp -pR ./luasrc/* $(1)/usr/lib/lua/luci
|
||||
$(INSTALL_DIR) $(1)/
|
||||
cp -pR ./root/* $(1)/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
po2lmo ./po/zh_Hans/koolproxy.po $(1)/usr/lib/lua/luci/i18n/koolproxy.zh-cn.lmo
|
||||
|
||||
ifeq ($(ARCH),mipsel)
|
||||
$(INSTALL_BIN) ./bin/mipsel $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),mips)
|
||||
$(INSTALL_BIN) ./bin/mips $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),x86)
|
||||
$(INSTALL_BIN) ./bin/x86 $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),x86_64)
|
||||
$(INSTALL_BIN) ./bin/x86_64 $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),arm)
|
||||
$(INSTALL_BIN) ./bin/arm $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
ifeq ($(ARCH),aarch64)
|
||||
$(INSTALL_BIN) ./bin/aarch64 $(1)/usr/share/koolproxy/koolproxy
|
||||
endif
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,luci-app-godproxy))
|
140
luci-app-godproxy/README.md
Normal file
140
luci-app-godproxy/README.md
Normal file
@ -0,0 +1,140 @@
|
||||
## 更新:2021年3月23日:
|
||||
感谢 [maple's sky](https://github.com/maplesky) 大佬提供技术支持,修复状态栏不动态问题。
|
||||
|
||||
## 更新:2021年3月4日:
|
||||
感谢 [xiaoqi2020](https://github.com/xiaoqi2020) 提供,选择规则托管国内。
|
||||
|
||||
## 更新:2021年2月26日(元宵):
|
||||
原来的码云以及coding规则已经无法获取(被封)了。现在托管在github上。
|
||||
|
||||
## 更名声明:
|
||||
原ledeproxy,于2021年1月23日更名为 GodProxy。特此知晓,以前的规则更新链接会失效!
|
||||
|
||||
## 整理声明:
|
||||
GodProxy是基于koolproxyR Plus+重新整理而来。主要参考:
|
||||
|
||||
1、以前Ameykyl大神的[KoolProxyR Plus+](https://github.com/Ameykyl/luci-app-koolproxyR) (源码已经2020年4月删除)。源码来源于[project-openwrt](https://github.com/project-openwrt/luci-app-koolproxyR)收录的ameykyl的2020年3月最后一次更新。
|
||||
|
||||
2、新的目录来源[Beginner-Go](https://github.com/Beginner-Go/luci-app-koolproxyR)
|
||||
|
||||
3、感谢koolproxy官方组、shaoxia、Ameykyl、project-openwrt组、Beginner-Go等的无私奉献!
|
||||
|
||||
4、规则来源于[GodProxy](https://github.com/godros/GodProxy) 。
|
||||
|
||||
## 本来是完全没有必要再造一个的,因为浪费时间。但各位大神都好久没有更新了,有些规则更新需要翻墙,有些名字是KP,有些是KPR,KPR Plus,KPR Plus+。所以没有办法,只能暂且叫GodProxy。望理解!
|
||||
|
||||
|
||||
## 免责声明:
|
||||
KoolProxy 是一个免费软件,著作权归属 KoolProxy.com,用户可以非商业性地复制和使用 KoolProxy,但禁止将 KoolProxy 用于商业用途。
|
||||
KoolProxy 可以对 https 网络数据进行识别代理,使用 https 功能的用户需要自己提供相关证书,本程序提供的证书生成脚本仅供用户参考,证书的保密工作由用户自行负责。
|
||||
使用本软件的风险由用户自行承担,在适用法律允许的最大范围内,对因使用本产品所产生的损害及风险,包括但不限于直接或间接的个人损害、商业赢利的丧失、贸易中断、商业信息的丢失或任何其它经济损失,KoolProxy.com 不承担任何责任。
|
||||
|
||||
## 1、前言
|
||||
感謝 koolshare.cn 提供 KoolProxy, 使用风险由用户自行承担
|
||||
本程序运行需要联网下载最新的 KoolProxy 到内存中运行, 也正因此本程序大小可以忽略不计.为了区分,暂且更名为:GodProxy
|
||||
|
||||
## 2、简介
|
||||
本软件包是 KoolProxy 的 LuCI 控制界面,
|
||||
|
||||
## 3、软件包文件结构:
|
||||
省
|
||||
|
||||
## 4、依赖
|
||||
软件包的正常使用需要依赖 curl, dnsmasq-full, iptables, ipset 和 dnsmasq-extra, openssl-util, diffutils, iptables-mod-nat-extra, wget, ca-bundle, ca-certificates, libustream-openssl
|
||||
|
||||
手动安装:在终端运行:
|
||||
opkg install openssl-util ipset dnsmasq-full diffutils iptables-mod-nat-extra wget ca-bundle ca-certificates libustream-openssl
|
||||
|
||||
如果没有 openssl ,就不能正常生成证书,导致https过滤失败!
|
||||
|
||||
如果没有 ipset, dnsmasq-full, diffutils,黑名单模式也会出现问题!(ipset 需要版本6),如果你的固件的busybox带有支持diff支持,那么diffutils包可以不安装
|
||||
|
||||
如果没有 iptables-mod-nat-extra ,会导致mac过滤失效!
|
||||
|
||||
如果没有 wget, ca-bundle, ca-certificates, libustream-openssl,lua-openssl,会导致规则文件更新失败,host规则条数变为0,如果你的固件的busybox带有支持https的wget,那么这几个包可以不安装。
|
||||
|
||||
|
||||
懒人版本,在.config文件里添加如下代码:
|
||||
|
||||
#koolproxy支持
|
||||
|
||||
CONFIG_PACKAGE_iptables-mod-nat-extra=y
|
||||
|
||||
CONFIG_PACKAGE_kmod-ipt-extra=y
|
||||
|
||||
CONFIG_PACKAGE_diffutils=y
|
||||
|
||||
CONFIG_PACKAGE_openssl-util=y
|
||||
|
||||
CONFIG_PACKAGE_dnsmasq-full=y
|
||||
|
||||
CONFIG_PACKAGE_ca-bundle=y
|
||||
|
||||
CONFIG_PACKAGE_ca-certificates=y
|
||||
|
||||
CONFIG_PACKAGE_libustream-openssl=y
|
||||
|
||||
CONFIG_PACKAGE_lua-openssl=y
|
||||
|
||||
|
||||
## 5、配置,
|
||||
软件包的配置文件路径: /etc/config/koolproxy
|
||||
此文件为 UCI 配置文件, 配置方式可参考 Wiki -> Use-UCI-system 和 OpenWrt Wiki
|
||||
|
||||
## 6、编译
|
||||
git clone https://github.com/godros/luci-app-godproxy.git package/luci-app-godproxy
|
||||
|
||||
make && sudo make install
|
||||
|
||||
选择要编译的包 LuCI -> 3. Applications
|
||||
|
||||
make menuconfig
|
||||
|
||||
开始编译
|
||||
|
||||
make package/feeds/luci-app-godproxy/compile V=s
|
||||
|
||||
# 7、关于IPv6支持(基于透明代理一刀切)
|
||||
需要在防火墙添加一条规则:
|
||||
|
||||
ip6tables -t nat -I PREROUTING -p tcp -j REDIRECT --to-ports 3000
|
||||
|
||||
```
|
||||
#已知副作用:
|
||||
#一刀切劫持内网所以设备的IPv6 TCP流量.
|
||||
#无法使用IPv6建立主动传入连接.
|
||||
#如果未安装证书,打开启用HTTPS的网站会报错.
|
||||
```
|
||||
|
||||
**NOTE:**
|
||||
|
||||
如果出现国外流量无法去广告(IPv4),请修改所使用代理的防火墙规则,必须让KP的规则在代理规则之上,检测命令:
|
||||
|
||||
``` bash
|
||||
iptables -t nat -L PREROUTING
|
||||
```
|
||||
|
||||
观察**KOOLPROXY**规则是否在所使用的代理的规则之上.
|
||||
|
||||
### 8、内置规则列表
|
||||
|
||||
[静态规则] [每日规则] [视频规则] [ipse] [adblock]
|
||||
|
||||
### 9、第三方规则(已做了转换,koolproxy能识别,不要用乘风大神的通用规则,会导致koolproxy停止运行)
|
||||
|
||||
[ABP规则]
|
||||
(ABP规则是CJX's Annoyance List+China+EasyList的二合一规则) 注:CJX's Annoyance List (反自我推广,移除anti adblock,防跟踪规则列表)是"EasyList China+EasyList" & "EasyPrivacy"的补充)
|
||||
|
||||
[Yhosts规则]
|
||||
|
||||
[Fanboy规则]
|
||||
|
||||
[AntiAD规则]
|
||||
|
||||
[乘风视频]
|
||||
|
||||
### 10、订阅规则(user1121114685大神和某位大神(忘记名字了)整合而成,能过滤youtube等)
|
||||
|
||||
[订阅规则]
|
||||
|
||||
### 首次运行koolproxy的时候,保存并提交速度较慢,因为会生成证书。
|
194
luci-app-godproxy/about-koolproxy.txt
Normal file
194
luci-app-godproxy/about-koolproxy.txt
Normal file
@ -0,0 +1,194 @@
|
||||
koolproxy插件/固件开发文档1.3
|
||||
更新日期:2017年7月7日(koolproxy 3.6.1)
|
||||
|
||||
================================================================================================
|
||||
声明:
|
||||
KoolProxy 是一个免费软件,著作权归属 KoolProxy.com,用户可以非商业性地复制和使用 KoolProxy,但禁止将 KoolProxy 用于商业用途。
|
||||
KoolProxy 可以对 https 网络数据进行识别代理,使用 https 功能的用户需要自己提供相关证书,本程序提供的证书生成脚本仅供用户参考,证书的保密工作由用户自行负责。
|
||||
使用本软件的风险由用户自行承担,在适用法律允许的最大范围内,对因使用本产品所产生的损害及风险,包括但不限于直接或间接的个人损害、商业赢利的丧失、贸易中断、商业信息的丢失或任何其它经济损失,KoolProxy.com 不承担任何责任。
|
||||
|
||||
================================================================================================
|
||||
KoolProxy By Xiaobao & Crwnet v3.6.1
|
||||
|
||||
USAGE:
|
||||
koolproxy [options] [arguments...]
|
||||
|
||||
OPTIONS:
|
||||
-p value listen port, default value is 3000
|
||||
-l value log level (0:DEBUG, 1:INFO, 2:AD, 3:WARNING, 4:ERROR), default value is ERROR
|
||||
-c value thread count, default value is the number of cpus
|
||||
-b value data path, default value is './data'
|
||||
-d run as daemon mode
|
||||
-v show version
|
||||
-h show help
|
||||
|
||||
ADVANCED:
|
||||
--cert generate ssl cert
|
||||
--ipv6 enable ipv6, works for ipv6 nat mode
|
||||
--video | -e video mode, load video rules only
|
||||
--mark mark mode, set the socket mark(src ip) when connect to remote host. requires the CAP_NET_ADMIN capability
|
||||
--ttl value ttl mode, set the socket ttl when connect to remote host. default value is 0 (disable)
|
||||
|
||||
================================================================================================
|
||||
交流地址:
|
||||
1 QQ群1: 595300867
|
||||
2 QQ群2: 203726739
|
||||
3 TG群: https://t.me/joinchat/AAAAAD-tO7GPvfOU131_vg
|
||||
4 更新日志:http://koolshare.cn/thread-64086-1-1.html
|
||||
|
||||
================================================================================================
|
||||
#koolproxy部署文件目录参考1(使用openssl生成证书)
|
||||
.
|
||||
├── data
|
||||
│ ├── gen_ca.sh #证书生成脚本
|
||||
│ ├── koolproxy_ipset.conf #ipset名单
|
||||
│ ├── openssl.cnf #证书生成所用配置文件
|
||||
│ ├── rules #规则存放文件夹
|
||||
│ │ ├── kp.dat #视频规则
|
||||
│ │ ├── koolproxy.txt #静态规则
|
||||
│ │ ├── daily.txt #每日规则
|
||||
│ │ └── user.txt #自定义规则
|
||||
│ └── version #插件版本号(merlin)
|
||||
└── koolproxy #koolproxy二进制(为了保证二进制顺利更新,请保证目录可写)
|
||||
|
||||
1 证书生成使用命令 sh gen_ca.sh,该脚本会调用系统内的openssl来生成证书,运行成功后会自动创建data/private data/cert目录
|
||||
私钥和公钥会分别存在data/private data/cert目录下,使用http://110.110.110.110会下载路由器内的证书
|
||||
|
||||
------------------------------------------------------------------------------------------------
|
||||
#koolproxy部署文件目录参考2(使用koolproxy生成证书)
|
||||
.
|
||||
└── koolproxy #koolproxy二进制(为了保证二进制顺利更新,请保证目录可写)
|
||||
1 因为规则文件会由koolproxy自动下载,下载后会自动创建data/rules目录
|
||||
2 使用koolproxy --cert命令可以生成证书,运行成功后会自动创建data/private data/cert目录
|
||||
私钥和公钥会分别存在data/private data/cert目录下,使用http://110.110.110.110会下载路由器内的证书
|
||||
因为mbedtls性能原因,在非软路由机器上用koolproxy --cert生成证书需要时间较长,请耐心等待
|
||||
|
||||
================================================================================================
|
||||
说明:
|
||||
1 koolproxy启动会自动检测规则更新,如果没有./data/rules文件夹,会自己创建并下载规则到此处
|
||||
2 koolproxy启动后会检测二进制文件更新,如果有更新,会替换./koolproxy,并且由父进程重启koolproxy,以后每20分钟检测一次更新
|
||||
3 现在不支持规则订阅了,只能识别kp.dat, koolproxy.txt, user.txt,daily.txt,需要自定义规则的可以修改user.txt
|
||||
|
||||
# 二进制下载固定地址
|
||||
https://koolproxy.com/downloads/i386
|
||||
https://koolproxy.com/downloads/x86_64
|
||||
https://koolproxy.com/downloads/arm
|
||||
https://koolproxy.com/downloads/mips
|
||||
https://koolproxy.com/downloads/mipsel
|
||||
|
||||
# 规则下载固定地址
|
||||
https://kprule.com/koolproxy.txt
|
||||
https://kprule.com/daily.txt
|
||||
https://kprule.com/kp.dat
|
||||
https://kprule.com/user.txt
|
||||
|
||||
# 规则下载对应的CDN地址
|
||||
https://kprules.b0.upaiyun.com/koolproxy.txt
|
||||
https://kprules.b0.upaiyun.com/daily.txt
|
||||
https://kprules.b0.upaiyun.com/kp.dat
|
||||
https://kprules.b0.upaiyun.com/user.txt
|
||||
|
||||
# 二进制文件和规则 github备份地址:
|
||||
二进制:https://github.com/koolproxy/koolproxy-bin (已作废)
|
||||
规则:https://github.com/koolproxy/koolproxy_rules (已作废)
|
||||
|
||||
|
||||
1 建议从上面的链接获取最新的二进制和基本的规则文件,然后按照上面的目录结构来部署
|
||||
2 如果不需要https过滤,只需要一个koolproxy程序就足够了,data文件夹和rules文件夹都会自己创建。
|
||||
3 koolproxy.txt内有视频规则、静态规则、每日规则的更新日期,可以用于提取并显示到界面
|
||||
|
||||
================================================================================================
|
||||
koolproxy运行:
|
||||
|
||||
1 在koolproxy主程序目录运行,例如merlin固件下运行:cd /koolshare/koolproxy && koolproxy -d
|
||||
2 不在koolproxy主程序目录运行(例如将koolproxy放在环境变量中),例如merlin固件下运行:koolproxy -b /koolshare/koolproxy -d -b为data路径
|
||||
其它运行方式可能会造成koolproxy识别不到data目录而无法加载规则
|
||||
koolproxy运行后默认会使用端口3000作为透明代理端口,需要利用iptables将数据导到端口3000才能发挥作用。
|
||||
|
||||
视频模式:
|
||||
1 使用命令koolproxy -e 即可开启
|
||||
2 开启后只会加载视频规则kp.dat和user.txt
|
||||
|
||||
调试模式:
|
||||
1 使用命令koolproxy -l0 即可开启,l后面的数字代表不同的日志详细程度
|
||||
2 需要检查规则命中行数可以需要使用-l2
|
||||
|
||||
ttl功能:
|
||||
1 使用命令koolproxy --ttl 160 即可开启ttl功能,后面的数值代表ttl大小
|
||||
2 ttl功能开启后,koolproxy会对经过它的所有数据ttl进行调整,可以利用iptables的match ttl功能数据进行匹配
|
||||
|
||||
mark功能:
|
||||
1 使用命令koolproxy --mark 即可开启mark功能
|
||||
2 mark功能开启后,koolproxy会对经过它的所有数据打上标记,mark值等于该数据的源ip转换为十六进制的值
|
||||
3 例如局域网内192.168.1.100的数据,将会被打上0xc0a80164的mark(192 = c0, 168 = a8, 1 = 01, 100 = 64 )
|
||||
4 开发者可以用此功和SS配合,达到既科学上网,又能过滤这些科学上网的流量,还不影响科学上网访问控制的功能
|
||||
5 ip转换为mark值参考命令:echo 192.168.1.100 | awk -F "." '{printf ("0x%02x", $1)} {printf ("%02x", $2)} {printf ("%02x", $3)} {printf ("%02x\n", $4)}'
|
||||
|
||||
================================================================================================
|
||||
ss + kp过滤方案(2017年7月7日):
|
||||
|
||||
方案1(优先SS,其次KP,不推荐):
|
||||
1 在NAT PREROUTING链内,SS在前,KP在后,流量将先走SS,经过SS分流后,国外流量走ss-redir,实现翻墙;
|
||||
2 而剩下国内流量在PREROUTING链内继续往下匹配到koolrpxy规则,流量最终走koolproxy,实现过滤。
|
||||
结果:koolproxy只能过滤国内流量(SS剩下的)。
|
||||
|
||||
方案2(优先KP,其次SS,不推荐);
|
||||
1 在NAT PREROUTING链内,KP在前,SS在后,流量将先走KP,实现过滤;
|
||||
2 为了SS能拿到KP过滤后的数据,使用match ttl匹配,在OUTPUT链内将流量全部给SS,实现翻墙;
|
||||
结果:因为在OUTPUT链内没有源ip信息,流量给SS后无法匹配到源ip,因此SS失去了acl(访问控制)功能。
|
||||
|
||||
方案3 (优先kp,其次SS,推荐);
|
||||
为便于理解,以下iptables配置只展示流量经过顺序,不是iptables的创建顺序,PREROUTING内规则的创建实际上应该在最后
|
||||
0 koolproxy默认开启ttl和mark功能 KoolProxy --ttl 160 --mark -d(固件不支持ttl的仅开启mark也行: KoolProxy --mark -d)
|
||||
1 在NAT PREROUTING链内,KP在前,SS在后,KP开启--mark,流量将先走KP(80,443),实现过滤,过滤后每个主机会被打上不同的mark;
|
||||
#KP在前,所有tcp流量全部交给KOOLPROXY链
|
||||
-A PREROUTING -p tcp -j KOOLPROXY
|
||||
#SS在后,在kp开启的时候,只能拿到非80,443的流量,在kp关闭后,可以拿到所有端口的流量
|
||||
-A PREROUTING -p tcp -j SHADOWSOCKS
|
||||
|
||||
2 例如局域网内192.168.1.100主机的数据经过kp过滤后,将会被打上0xc0a80164的mark(192 = c0, 168 = a8, 1 = 01, 100 = 64 );
|
||||
#创建KOOLPROXY链,用于白名单和访问控制
|
||||
-N KOOLPROXY
|
||||
#创建KOOLPROXY_HTTP链,用于过滤http流量
|
||||
-N KOOLPROXY_HTTP
|
||||
#创建KOOLPROXY_HTTPS链,用于过滤https流量
|
||||
-N KOOLPROXY_HTTPS
|
||||
#局域网和保留地址不走kp
|
||||
-A KOOLPROXY -m set --match-set white_kp_list dst -j RETURN
|
||||
#主机192.168.1.100需要https过滤
|
||||
-A KOOLPROXY -s 192.168.1.100/32 -p tcp -g KOOLPROXY_HTTPS
|
||||
#其它主机过滤http流量
|
||||
-A KOOLPROXY -p tcp -j KOOLPROXY_HTTP
|
||||
|
||||
3 为了SS能拿到数据,在NAT OUTPUT链中,使用match ttl匹配,在OUTPUT链内将流量全部给SHADOWSOCKS_EXT链;
|
||||
#创建SHADOWSOCKS_EXT链,用于开启kp情况下ss的访问控制实现
|
||||
-N SHADOWSOCKS_EXT
|
||||
#使用ttl匹配将KP过滤后的数据转到SHADOWSOCKS_EXT链(如果固件不支持ttl匹配,使用下面的命令)
|
||||
-A OUTPUT -p tcp -m ttl --ttl-eq 160 -j SHADOWSOCKS_EXT
|
||||
#如果固件不支持ttl match,可以用mark匹配ip地址的前三位(用0xffffff00作为掩码的形式),来将KP过滤后的数据转到SHADOWSOCKS_EXT链
|
||||
# echo 192.168.1 | awk -F "." '{printf ("0x%02x", $1)} {printf ("%02x", $2)} {printf ("%02x", $3)} {printf ("00/0xffffff00\n")}' = 0xc0a80100/0xffffff00
|
||||
-A OUTPUT -p tcp -m mark --mark 0xc0a80100/0xffffff00 -j SHADOWSOCKS_EXT
|
||||
|
||||
4 如果开启了acl,比如需要192.168.1.75不走SS(全端口),192.168.1.246走gfwlist模式(80,443端口),192.168.1.214走大陆白名单模式(22,80,443端口),剩余主机全部走大陆白名单模式(全端口):
|
||||
#主机192.168.1.75(0xc0a8014b),流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,而未能翻墙(RETURN)
|
||||
-A SHADOWSOCKS_EXT -p tcp -m mark --mark 0xc0a8014b -j RETURN
|
||||
#主机192.168.1.246(0xc0a801f6),流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,在此流量被导向了SHADOWSOCKS_GFW链,实现gfwlist模式翻墙(80,443端口)
|
||||
-A SHADOWSOCKS_EXT -p tcp -m multiport --dports 80,443 -m mark --mark 0xc0a801f6 -g SHADOWSOCKS_GFW
|
||||
#主机192.168.1.214(0xc0a801f6),流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,在此流量被导向了SHADOWSOCKS_CHN链,实现大陆白名单模式翻墙(22,80,443端口)
|
||||
-A SHADOWSOCKS_EXT -p tcp -m multiport --dports 22,,80,443 -m mark --mark 0xc0a801d6 -g SHADOWSOCKS_CHN
|
||||
#剩余的主机,流量经过KP过滤后并打上mark后,通过OUTPUT链进入SHADOWSOCKS_EXT链,在此流量被导向了SHADOWSOCKS_CHN链,实现大陆白名单模式翻墙(全端口)
|
||||
-A SHADOWSOCKS_EXT -p tcp -j SHADOWSOCKS_CHN
|
||||
|
||||
情形:
|
||||
1 当SS开启,kp未开启:所有流量走ss PREROUTING过,经过分流后,国内的流量在经过OUTPUT的时候,因为KP没开,数据不会匹配到ttl值(或者没匹配到mark值),所以不会过滤广告,翻墙正常
|
||||
2 当KP开启,SS未开启,所有流量走kp PREROUTING过,广告过滤正常
|
||||
3 当SS开启,翻墙和acl工作正常的时候,开启KP:KP在PREROUTING内插入到SS前面,会先得到流量,广告过滤正常
|
||||
4 当KP开启,过滤广告正常的时候,开启SS:SS从原来的从PREROUTING拿流量变成从OUTPUT内拿流量,翻墙和acl会同样正常
|
||||
5 当KP和SS都开启,此时关闭SS,kp过滤广告正常
|
||||
6 当KP和SS都开启,此时关闭KP,ss翻墙和acl正常
|
||||
|
||||
总结:
|
||||
使用 ttl + mark (或者纯mark)的方式,可以实现原先很难实现的过滤经过SS流量的广告
|
||||
主要的改动在于给SS预置好OUTPUT和SHADOWSOCKS_EXT规则链,当kp启用时,它们就会工作,kp关闭时,不会影响正常数据
|
||||
次要的改动就是给koolproxy默认开启ttl + mark(或者纯mark)功能
|
||||
================================================================================================
|
BIN
luci-app-godproxy/bin/aarch64
Executable file
BIN
luci-app-godproxy/bin/aarch64
Executable file
Binary file not shown.
BIN
luci-app-godproxy/bin/arm
Executable file
BIN
luci-app-godproxy/bin/arm
Executable file
Binary file not shown.
BIN
luci-app-godproxy/bin/mips
Executable file
BIN
luci-app-godproxy/bin/mips
Executable file
Binary file not shown.
BIN
luci-app-godproxy/bin/mipsel
Executable file
BIN
luci-app-godproxy/bin/mipsel
Executable file
Binary file not shown.
BIN
luci-app-godproxy/bin/x86
Executable file
BIN
luci-app-godproxy/bin/x86
Executable file
Binary file not shown.
BIN
luci-app-godproxy/bin/x86_64
Executable file
BIN
luci-app-godproxy/bin/x86_64
Executable file
Binary file not shown.
16
luci-app-godproxy/luasrc/controller/koolproxy.lua
Normal file
16
luci-app-godproxy/luasrc/controller/koolproxy.lua
Normal file
@ -0,0 +1,16 @@
|
||||
module("luci.controller.koolproxy",package.seeall)
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/koolproxy")then
|
||||
return
|
||||
end
|
||||
entry({"admin","services","koolproxy"},cbi("koolproxy/global"),_("GodProxy滤广告"),1).dependent=true
|
||||
entry({"admin","services","koolproxy","rss_rule"},cbi("koolproxy/rss_rule"), nil).leaf=true
|
||||
entry({"admin","services","koolproxy","status"},call("act_status")).leaf=true
|
||||
end
|
||||
|
||||
function act_status()
|
||||
local e={}
|
||||
e.koolproxy=luci.sys.call("pidof %s >/dev/null"%"koolproxy")==0
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(e)
|
||||
end
|
409
luci-app-godproxy/luasrc/model/cbi/koolproxy/global.lua
Normal file
409
luci-app-godproxy/luasrc/model/cbi/koolproxy/global.lua
Normal file
@ -0,0 +1,409 @@
|
||||
-- Copyright 2018 Nick Peng (pymumu@gmail.com)
|
||||
|
||||
require ("nixio.fs")
|
||||
require ("luci.http")
|
||||
require ("luci.dispatcher")
|
||||
require ("nixio.fs")
|
||||
|
||||
local fs = require "nixio.fs"
|
||||
local sys = require "luci.sys"
|
||||
local http = require "luci.http"
|
||||
|
||||
|
||||
local o,t,e
|
||||
local v=luci.sys.exec("/usr/share/koolproxy/koolproxy -v")
|
||||
local a=luci.sys.exec("head -3 /usr/share/koolproxy/data/rules/koolproxy.txt | grep rules | awk -F' ' '{print $3,$4}'")
|
||||
local b=luci.sys.exec("head -4 /usr/share/koolproxy/data/rules/koolproxy.txt | grep video | awk -F' ' '{print $3,$4}'")
|
||||
local c=luci.sys.exec("head -3 /usr/share/koolproxy/data/rules/daily.txt | grep rules | awk -F' ' '{print $3,$4}'")
|
||||
local s=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/easylistchina.txt | wc -l")
|
||||
local m=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/mv.txt | wc -l")
|
||||
local u=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/fanboy.txt | wc -l")
|
||||
local p=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/yhosts.txt | wc -l")
|
||||
local h=luci.sys.exec("grep -v '^!' /usr/share/koolproxy/data/rules/user.txt | wc -l")
|
||||
local l=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/koolproxy.txt | wc -l")
|
||||
local q=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/daily.txt | wc -l")
|
||||
local f=luci.sys.exec("grep -v !x /usr/share/koolproxy/data/rules/anti-ad.txt | wc -l")
|
||||
local i=luci.sys.exec("cat /usr/share/koolproxy/dnsmasq.adblock | wc -l")
|
||||
|
||||
|
||||
if luci.sys.call("pidof koolproxy >/dev/null") == 0 then
|
||||
status = translate("<strong class=\"koolproxy_status\"><font color=\"green\">GodProxy滤广告 运行中</font></strong>")
|
||||
else
|
||||
status = translate("<strong class=\"koolproxy_status\"><font color=\"red\">GodProxy滤广告 未运行</font></strong>")
|
||||
end
|
||||
|
||||
o = Map("koolproxy", translate("GodProxy滤广告 "), translate("GodProxy是基于KoolProxyR Plus重新整理的能识别adblock规则的免费开源软件,追求体验更快、更清洁的网络,屏蔽烦人的广告!"))
|
||||
|
||||
o.template="koolproxy/koolproxy_status"
|
||||
t = o:section(TypedSection, "global")
|
||||
t.anonymous = true
|
||||
t.description = translate(string.format("%s<br /><br />", status))
|
||||
|
||||
t:tab("base",translate("Basic Settings"))
|
||||
|
||||
e = t:taboption("base", Flag, "enabled", translate("Enable"))
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
|
||||
e = t:taboption("base", DummyValue, "koolproxy_status", translate("程序版本"))
|
||||
e.value = string.format("[ %s ]", v)
|
||||
|
||||
e = t:taboption("base", Value, "startup_delay", translate("启动延迟"))
|
||||
e:value(0, translate("不启用"))
|
||||
for _, v in ipairs({5, 10, 15, 25, 40, 60}) do
|
||||
e:value(v, translate("%u 秒") %{v})
|
||||
end
|
||||
e.datatype = "uinteger"
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_mode", translate("Filter Mode"))
|
||||
e.default = 1
|
||||
e.rmempty = false
|
||||
e:value(1, translate("全局模式"))
|
||||
e:value(2, translate("IPSET模式"))
|
||||
e:value(3, translate("视频模式"))
|
||||
|
||||
e = t:taboption("base", MultiValue, "koolproxy_rules", translate("内置规则"))
|
||||
e.optional = false
|
||||
e.rmempty = false
|
||||
e:value("koolproxy.txt", translate("静态规则"))
|
||||
e:value("daily.txt", translate("每日规则"))
|
||||
e:value("kp.dat", translate("视频规则"))
|
||||
e:value("user.txt", translate("自定义规则"))
|
||||
|
||||
e = t:taboption("base", MultiValue, "thirdparty_rules", translate("第三方规则"))
|
||||
e.optional = true
|
||||
e.rmempty = false
|
||||
e:value("easylistchina.txt", translate("ABP规则"))
|
||||
e:value("fanboy.txt", translate("Fanboy规则"))
|
||||
e:value("yhosts.txt", translate("Yhosts规则"))
|
||||
e:value("anti-ad.txt", translate("Anti-AD规则"))
|
||||
e:value("mv.txt", translate("乘风视频"))
|
||||
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_port", translate("端口控制"))
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
e:value(0, translate("关闭"))
|
||||
e:value(1, translate("开启"))
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_ipv6", translate("IPv6支持"))
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
e:value(0, translate("关闭"))
|
||||
e:value(1, translate("开启"))
|
||||
|
||||
e = t:taboption("base", Value, "koolproxy_bp_port", translate("例外端口"))
|
||||
e:depends("koolproxy_port", "1")
|
||||
e.rmempty = false
|
||||
e.description = translate(string.format("<font color=\"red\"><strong>单端口:80 多端口:80,443</strong></font>"))
|
||||
|
||||
e=t:taboption("base",Flag,"koolproxy_host",translate("开启Adblock Plus Hosts"))
|
||||
e.default=0
|
||||
e:depends("koolproxy_mode","2")
|
||||
|
||||
|
||||
e = t:taboption("base", ListValue, "koolproxy_acl_default", translate("默认访问控制"))
|
||||
e.default = 1
|
||||
e.rmempty = false
|
||||
e:value(0, translate("不过滤"))
|
||||
e:value(1, translate("过滤HTTP协议"))
|
||||
e:value(2, translate("过滤HTTP(S)协议"))
|
||||
e:value(3, translate("全部过滤"))
|
||||
e.description = translate(string.format("<font color=\"blue\"><strong>访问控制设置中其他主机的默认规则</strong></font>"))
|
||||
|
||||
e = t:taboption("base", ListValue, "time_update", translate("定时更新"))
|
||||
|
||||
for t = 0,23 do
|
||||
|
||||
e:value(t,translate("每天"..t.."点"))
|
||||
end
|
||||
e:value(nil, translate("关闭"))
|
||||
e.default = 0
|
||||
e.rmempty = false
|
||||
e.description = translate(string.format("<font color=\"red\"><strong>定时更新规则。请把时间修改掉,默认时间使用人数多会更新失败</strong></font>"))
|
||||
|
||||
e = t:taboption("base", Button, "restart", translate("规则状态"))
|
||||
e.inputtitle = translate("更新规则")
|
||||
e.inputstyle = "reload"
|
||||
e.write = function()
|
||||
luci.sys.call("/usr/share/koolproxy/kpupdate 2>&1 >/dev/null")
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","services","koolproxy"))
|
||||
end
|
||||
e.description = translate(string.format("<font color=\"red\"><strong>更新订阅规则与Adblock Plus Hosts</strong></font><br /><font color=\"green\">ABP规则: %s条<br />Fanboy规则: %s条<br />Yhosts规则: %s条<br />Anti-AD规则: %s条<br />静态规则: %s条<br />视频规则: %s<br />乘风视频: %s条<br />每日规则: %s条<br />自定义规则: %s条<br />Host: %s条</font><br />", s, u, p, f, l, b, m, q, h, i))
|
||||
t:tab("cert",translate("Certificate Management"))
|
||||
|
||||
e=t:taboption("cert",DummyValue,"c1status",translate("<div align=\"left\"><strong>证书恢复</strong></div>"))
|
||||
e=t:taboption("cert",FileUpload,"")
|
||||
e.template="koolproxy/caupload"
|
||||
e=t:taboption("cert",DummyValue,"",nil)
|
||||
e.template="koolproxy/cadvalue"
|
||||
if nixio.fs.access("/usr/share/koolproxy/data/certs/ca.crt")then
|
||||
e=t:taboption("cert",DummyValue,"c2status",translate("<div align=\"left\"><strong>证书备份</strong></div>"))
|
||||
e=t:taboption("cert",Button,"certificate")
|
||||
e.inputtitle=translate("Backup Download")
|
||||
e.inputstyle="reload"
|
||||
e.write=function()
|
||||
luci.sys.call("/usr/share/koolproxy/camanagement backup 2>&1 >/dev/null")
|
||||
Download()
|
||||
luci.http.redirect(luci.dispatcher.build_url("admin","services","koolproxy"))
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
t:tab("white_weblist",translate("网站白名单设置"))
|
||||
|
||||
local i = "/etc/adblocklist/adbypass"
|
||||
e = t:taboption("white_weblist", TextValue, "adbypass_domain")
|
||||
e.description = translate("这些已经加入的网站将不会使用过滤器。请输入网站的域名,每行只能输入一个网站域名。例如google.com。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adbypass", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adbypass /etc/adblocklist/adbypass") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adbypass")
|
||||
end
|
||||
|
||||
t:tab("weblist",translate("Set Backlist Of Websites"))
|
||||
|
||||
local i = "/etc/adblocklist/adblock"
|
||||
e = t:taboption("weblist", TextValue, "adblock_domain")
|
||||
e.description = translate("加入的网址将走广告过滤端口。只针对黑名单模式。只能输入WEB地址,如:google.com,每个地址一行。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adblock", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adblock /etc/adblocklist/adblock") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adblock")
|
||||
end
|
||||
|
||||
t:tab("white_iplist",translate("IP白名单设置"))
|
||||
|
||||
local i = "/etc/adblocklist/adbypassip"
|
||||
e = t:taboption("white_iplist", TextValue, "adbypass_ip")
|
||||
e.description = translate("这些已加入的ip地址将使用代理,但只有GFW型号。请输入ip地址或ip地址段,每行只能输入一个ip地址。例如,112.123.134.145 / 24或112.123.134.145。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adbypassip", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adbypassip /etc/adblocklist/adbypassip") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adbypassip")
|
||||
end
|
||||
|
||||
t:tab("iplist",translate("IP黑名单设置"))
|
||||
|
||||
local i = "/etc/adblocklist/adblockip"
|
||||
e = t:taboption("iplist", TextValue, "adblock_ip")
|
||||
e.description = translate("这些已经加入的ip地址不会使用过滤器.请输入ip地址或ip地址段,每行只能输入一个ip地址。例如,112.123.134.145 / 24或112.123.134.145。")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/adblockip", value)
|
||||
if (luci.sys.call("cmp -s /tmp/adblockip /etc/adblocklist/adblockip") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/adblockip")
|
||||
end
|
||||
|
||||
t:tab("customlist", translate("Set Backlist Of custom"))
|
||||
|
||||
local i = "/usr/share/koolproxy/data/user.txt"
|
||||
e = t:taboption("customlist", TextValue, "user_rule")
|
||||
e.description = translate("Enter your custom rules, each row.")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
if value then
|
||||
value = value:gsub("\r\n", "\n")
|
||||
else
|
||||
value = ""
|
||||
end
|
||||
fs.writefile("/tmp/user.txt", value)
|
||||
if (luci.sys.call("cmp -s /tmp/user.txt /usr/share/koolproxy/data/user.txt") == 1) then
|
||||
fs.writefile(i, value)
|
||||
end
|
||||
fs.remove("/tmp/user.txt")
|
||||
end
|
||||
|
||||
t:tab("logs",translate("View the logs"))
|
||||
|
||||
local i = "/var/log/koolproxy.log"
|
||||
e = t:taboption("logs", TextValue, "kpupdate_log")
|
||||
e.description = translate("Koolproxy Logs")
|
||||
e.rows = 28
|
||||
e.wrap = "off"
|
||||
e.rmempty = false
|
||||
|
||||
function e.cfgvalue()
|
||||
return fs.readfile(i) or ""
|
||||
end
|
||||
|
||||
function e.write(self, section, value)
|
||||
end
|
||||
|
||||
t=o:section(TypedSection,"acl_rule",translate("GodProxy 访问控制"),
|
||||
translate("ACLs is a tools which used to designate specific IP filter mode,The MAC addresses added to the list will be filtered using https"))
|
||||
t.template="cbi/tblsection"
|
||||
t.sortable=true
|
||||
t.anonymous=true
|
||||
t.addremove=true
|
||||
e=t:option(Value,"remarks",translate("Client Remarks"))
|
||||
e.width="30%"
|
||||
e.rmempty=true
|
||||
e=t:option(Value,"ipaddr",translate("IP Address"))
|
||||
e.width="20%"
|
||||
e.datatype="ip4addr"
|
||||
luci.ip.neighbors({family = 4}, function(neighbor)
|
||||
if neighbor.reachable then
|
||||
e:value(neighbor.dest:string(), "%s (%s)" %{neighbor.dest:string(), neighbor.mac})
|
||||
end
|
||||
end)
|
||||
e=t:option(Value,"mac",translate("MAC Address"))
|
||||
e.width="20%"
|
||||
e.rmempty=true
|
||||
e.datatype="macaddr"
|
||||
luci.ip.neighbors({family = 4}, function(neighbor)
|
||||
if neighbor.reachable then
|
||||
e:value(neighbor.mac, "%s (%s)" %{neighbor.mac, neighbor.dest:string()})
|
||||
end
|
||||
end)
|
||||
e=t:option(ListValue,"proxy_mode",translate("访问控制"))
|
||||
e.width="20%"
|
||||
e.default=1
|
||||
e.rmempty=false
|
||||
e:value(0,translate("不过滤"))
|
||||
e:value(1,translate("过滤 HTTP"))
|
||||
e:value(2,translate("过滤HTTP + HTTPS"))
|
||||
e:value(3,translate("过滤全端口"))
|
||||
|
||||
t=o:section(TypedSection,"rss_rule",translate("GodProxy 规则订阅"), translate("请确保订阅规则的兼容性"))
|
||||
t.anonymous=true
|
||||
t.addremove=true
|
||||
t.sortable=true
|
||||
t.template="cbi/tblsection"
|
||||
t.extedit=luci.dispatcher.build_url("admin/services/koolproxy/rss_rule/%s")
|
||||
|
||||
t.create=function(...)
|
||||
local sid=TypedSection.create(...)
|
||||
if sid then
|
||||
luci.http.redirect(t.extedit % sid)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
e=t:option(Flag,"load",translate("启用"))
|
||||
e.default=0
|
||||
e.rmempty=false
|
||||
|
||||
e=t:option(DummyValue,"name",translate("规则名称"))
|
||||
function e.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("None")
|
||||
end
|
||||
|
||||
e=t:option(DummyValue,"url",translate("规则地址"))
|
||||
function e.cfgvalue(...)
|
||||
return Value.cfgvalue(...) or translate("None")
|
||||
end
|
||||
|
||||
e=t:option(DummyValue,"time",translate("更新时间"))
|
||||
|
||||
function Download()
|
||||
local t,e
|
||||
t=nixio.open("/tmp/upload/koolproxyca.tar.gz","r")
|
||||
luci.http.header('Content-Disposition','attachment; filename="koolproxyCA.tar.gz"')
|
||||
luci.http.prepare_content("application/octet-stream")
|
||||
while true do
|
||||
e=t:read(nixio.const.buffersize)
|
||||
if(not e)or(#e==0)then
|
||||
break
|
||||
else
|
||||
luci.http.write(e)
|
||||
end
|
||||
end
|
||||
t:close()
|
||||
luci.http.close()
|
||||
end
|
||||
local t,e
|
||||
t="/tmp/upload/"
|
||||
nixio.fs.mkdir(t)
|
||||
luci.http.setfilehandler(
|
||||
function(o,a,i)
|
||||
if not e then
|
||||
if not o then return end
|
||||
e=nixio.open(t..o.file,"w")
|
||||
if not e then
|
||||
return
|
||||
end
|
||||
end
|
||||
if a and e then
|
||||
e:write(a)
|
||||
end
|
||||
if i and e then
|
||||
e:close()
|
||||
e=nil
|
||||
luci.sys.call("/usr/share/koolproxy/camanagement restore 2>&1 >/dev/null")
|
||||
end
|
||||
end
|
||||
)
|
||||
|
||||
t=o:section(TypedSection,"usetips",translate("GodProxy 帮助支持"))
|
||||
t.anonymous = true
|
||||
t:append(Template("koolproxy/feedback"))
|
||||
return o
|
36
luci-app-godproxy/luasrc/model/cbi/koolproxy/rss_rule.lua
Normal file
36
luci-app-godproxy/luasrc/model/cbi/koolproxy/rss_rule.lua
Normal file
@ -0,0 +1,36 @@
|
||||
local m, s, o
|
||||
local koolproxy = "koolproxy"
|
||||
local sid = arg[1]
|
||||
|
||||
m = Map(koolproxy, "%s - %s" %{translate("GodProxy滤广告"), translate("编辑规则")})
|
||||
m.redirect = luci.dispatcher.build_url("admin/services/koolproxy")
|
||||
|
||||
if not arg[1] or m.uci:get(koolproxy, sid) ~= "rss_rule" then
|
||||
luci.http.redirect(m.redirect)
|
||||
return
|
||||
end
|
||||
|
||||
-- [[ Edit Rule ]]--
|
||||
s = m:section(NamedSection, sid, "rss_rule")
|
||||
s.anonymous = true
|
||||
s.addremove = true
|
||||
|
||||
o=s:option(Flag,"load",translate("启用"))
|
||||
o.default=0
|
||||
o.rmempty=false
|
||||
|
||||
o=s:option(Value,"name",translate("规则描述"))
|
||||
o.rmempty=true
|
||||
|
||||
o=s:option(Value,"url",translate("规则地址"))
|
||||
o.rmempty=false
|
||||
o.placeholder="[https|http|ftp]://[Hostname]/[File]"
|
||||
function o.validate(self, value)
|
||||
if not value then
|
||||
return nil
|
||||
else
|
||||
return value
|
||||
end
|
||||
end
|
||||
|
||||
return m
|
8
luci-app-godproxy/luasrc/view/koolproxy/cadvalue.htm
Normal file
8
luci-app-godproxy/luasrc/view/koolproxy/cadvalue.htm
Normal file
@ -0,0 +1,8 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span style="color: green">
|
||||
<%
|
||||
local val = self:cfgvalue(section) or self.default or ""
|
||||
write(pcdata(val))
|
||||
%>
|
||||
</span>
|
||||
<%+cbi/valuefooter%>
|
5
luci-app-godproxy/luasrc/view/koolproxy/caupload.htm
Normal file
5
luci-app-godproxy/luasrc/view/koolproxy/caupload.htm
Normal file
@ -0,0 +1,5 @@
|
||||
<%+cbi/valueheader%>
|
||||
<label class="cbi-value" style="display:inline-block; width: 400px" for="ulfile"><font color="red"><%:Upload backup file,The file name must be koolproxyCA.tar.gz%></font></label><br />
|
||||
<input class="cbi-input-file" style="width: 400px" type="file" id="ulfile" name="ulfile" />
|
||||
<input type="submit" class="cbi-button cbi-input-apply" name="upload" value="<%:Upload Restore%>" />
|
||||
<%+cbi/valuefooter%>
|
3
luci-app-godproxy/luasrc/view/koolproxy/dvalue.htm
Normal file
3
luci-app-godproxy/luasrc/view/koolproxy/dvalue.htm
Normal file
@ -0,0 +1,3 @@
|
||||
<%+cbi/valueheader%>
|
||||
<span class="koolproxy_status"><%=pcdata(self:cfgvalue(section) or self.default or "")%></span>
|
||||
<%+cbi/valuefooter%>
|
31
luci-app-godproxy/luasrc/view/koolproxy/feedback.htm
Normal file
31
luci-app-godproxy/luasrc/view/koolproxy/feedback.htm
Normal file
@ -0,0 +1,31 @@
|
||||
</style>
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">GodProxy重要简洁的使用Tips:</label>
|
||||
<div class="cbi-value-field">
|
||||
<br />
|
||||
1、 推荐配置:过滤模式(全局模式)+ 默认访问控制(过滤http协议)达到最佳的过滤效果。
|
||||
<br />
|
||||
2、 使用步骤:A、更新规则,B、恢复证书,C、设置要过滤的https客户端ip,D、清除浏览器或APP数据。
|
||||
<br />
|
||||
3、 Adblock Plus的Host列表 + KoolProxy黑名单模式运行更流畅上网体验。
|
||||
<br />
|
||||
4、 要过滤视频广告,必须选中规则中的视频规则。因为其他规则里面已经剔除了视频的网站。
|
||||
<br />
|
||||
5、 过滤HTTPS广告需要为相应客户端安装证书,在“控制控制”里添加客户端ip或者mac地址,并选择用<u><font color='#FF0000'>HTTP + HTTPS</font></u>过滤!
|
||||
<br />
|
||||
6、 在路由器下的设备,在浏览器中输入<u><font color='#FF0000'>110.110.110.110</font></u>来下载证书,导入证书目录请选择“受信任的根证书颁发机构”。
|
||||
<br />
|
||||
7、 安装完证书后,请清除浏览器的缓存、视频APP的全部数据。如果访问网页弹出不安全提示,请检查证书是否安装正确。
|
||||
<br />
|
||||
8、 如果想在多台路由器上使用一个证书,请先备份证书,然后再在另一个路由器上恢复证书即可。
|
||||
<br />
|
||||
</div>
|
||||
|
||||
<div class="cbi-value">
|
||||
<label class="cbi-value-title">Shaoxia的KoolProxyR详细使用说明</label>
|
||||
<div class="cbi-value-field">
|
||||
<input type="button" class="cbi-button cbi-input-reload" value="点击前往" onclick="javascript:window.open('https://shaoxia.xyz/post/koolproxyr%E6%8C%87%E5%8D%97/','target');" />
|
||||
</div>
|
||||
</div>
|
||||
</fieldset>
|
||||
</fieldset>
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user