mirror of
https://github.com/kenzok8/small-package
synced 2025-09-18 18:51:16 +08:00
update-09.24
This commit is contained in:
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中,右键单击,将其锁定,方便以后打开。如下图:
|
||||
|
||||
打开终端后,在其中输入如下命令:
|
||||
```
|
||||
$ 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
|
||||
|
||||
对于极壹,调整好后应该如下图所示:
|
||||
|
||||

|
||||
|
||||
对于小米Mini,调整好应该如下图所示:
|
||||
|
||||

|
||||
|
||||
下面一步,就是把我们要编译的软件包含进去。
|
||||
|
||||
在Makefile里面我们已经知道,这个软件包是属于Network里的Ruijie,所以我们在主菜单中找到Network,回车进入,然后找到Ruijie这一项
|
||||
|
||||

|
||||
|
||||
然后到这里
|
||||
|
||||

|
||||
|
||||
这里不要按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包,可以一并安装。
|
||||
|
||||

|
||||
|
||||
## Install
|
||||
|
||||
将上面拷贝出来的mentohust及libpcap的ipk,用上面的方法,利用WinSCP上传到路由器的tmp目录。这个操作很简单,这里不再赘述。
|
||||
|
||||
使用快捷键`Ctrl+P`打开PuTTY,输入密码(默认是admin)回车后,来到如下界面:
|
||||
|
||||

|
||||
|
||||
然后我们先`cd /tmp/`
|
||||
然后用`opkg`命令安装我们所需的软件包:
|
||||
|
||||
```
|
||||
opkg install libpcap_1.7.4-1_ramips_24kec.ipk
|
||||
opkg install mentohust_0.3.1-1_ramips_24kec.ipk
|
||||
```
|
||||
|
||||
这时有可能会出现这种情况:
|
||||
|
||||

|
||||
|
||||
遇到这种错误,需要修改/etc/opkg.conf文件,对于小米Mini,需要在其尾部追加:
|
||||
|
||||
```
|
||||
arch all 1
|
||||
arch ralink 200
|
||||
arch ramips_24kec 100
|
||||
```
|
||||
|
||||
这样就能正确地安装了:
|
||||
|
||||

|
||||
|
||||
当然,mentohust也可以了:
|
||||
|
||||

|
||||
|
||||
在有些比较老的路由器固件中安装,会有类似这样的错误:
|
||||
|
||||
> //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
|
@ -7,7 +7,7 @@ include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=adguardhome
|
||||
PKG_VERSION:=0.107.0-b.11
|
||||
PKG_RELEASE:=10
|
||||
PKG_RELEASE:=
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_VERSION:=48b0cefb29b67cee2171a9eacda9f06f8380b02b
|
||||
|
100
amule/Makefile
Normal file
100
amule/Makefile
Normal file
@ -0,0 +1,100 @@
|
||||
# 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:=amule
|
||||
PKG_VERSION:=2.3.3
|
||||
PKG_RELEASE:=1
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/amule-project/amule/tar.gz/$(PKG_VERSION)?
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_CONFIG_DEPEDS:= CONFIG_AMULE_CRYPTOPP_STATIC_LINKING
|
||||
|
||||
PKG_FIXUP:=autoreconf
|
||||
PKG_BUILD_DEPENDS:=libcryptopp libgd
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/nls.mk
|
||||
|
||||
define Package/amule
|
||||
SUBMENU:=P2P
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=A multi-platform eMule-like ed2k client
|
||||
URL:=http://www.amule.org/
|
||||
DEPENDS:=+libpng +libpthread +libncurses +libreadline +libwxbase +libupnp +libbfd \
|
||||
$(ICONV_DEPENDS) $(INTL_DEPENDS) +!AMULE_CRYPTOPP_STATIC_LINKING:libcryptopp
|
||||
endef
|
||||
|
||||
define Package/amule/config
|
||||
config AMULE_CRYPTOPP_STATIC_LINKING
|
||||
bool "Link libcryptopp statically"
|
||||
default n
|
||||
endef
|
||||
|
||||
TARGET_LDFLAGS+= -liconv
|
||||
|
||||
CONFIGURE_ARGS+= \
|
||||
--disable-static \
|
||||
--disable-rpath \
|
||||
--disable-ccache \
|
||||
--disable-optimize \
|
||||
--disable-profile \
|
||||
--disable-monolithic \
|
||||
--enable-amule-daemon \
|
||||
--enable-amulecmd \
|
||||
--enable-webserver \
|
||||
--disable-amule-gui \
|
||||
--disable-cas \
|
||||
--disable-wxcas \
|
||||
--disable-ed2k \
|
||||
--disable-alc \
|
||||
--disable-alcc \
|
||||
--disable-debug \
|
||||
--disable-fileview \
|
||||
--disable-plasmamule \
|
||||
--without-wxdebug \
|
||||
--enable-dlp \
|
||||
--enable-upnp \
|
||||
--with-gnu-ld \
|
||||
--with-zlib="$(STAGING_DIR)/usr" \
|
||||
--with-gdlib-prefix="$(STAGING_DIR)/usr" \
|
||||
--with-libpng-prefix="$(STAGING_DIR)/usr" \
|
||||
--with-wx-prefix="$(STAGING_DIR)/usr" \
|
||||
--with-crypto-prefix="$(STAGING_DIR)/usr" \
|
||||
--with-libiconv-prefix="$(ICONV_PREFIX)" \
|
||||
--with-libintl-prefix="$(INTL_PREFIX)" \
|
||||
--with-libupnp-prefix="$(STAGING_DIR)/usr" \
|
||||
--without-x
|
||||
|
||||
MAKE_FLAGS += HOSTCC="$(HOSTCC)"
|
||||
|
||||
define Build/Configure
|
||||
cd $(PKG_BUILD_DIR); $(SHELL) autogen.sh
|
||||
$(call Build/Configure/Default)
|
||||
ifeq ($(CONFIG_AMULE_CRYPTOPP_STATIC_LINKING),y)
|
||||
$(SED) 's;^CRYPTOPP_LIBS.*;CRYPTOPP_LIBS \= "$(STAGING_DIR)/usr/lib/libcryptopp.a";g' \
|
||||
$(PKG_BUILD_DIR)/src/Makefile
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/amule/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/amulecmd $(1)/usr/bin/amulecmd
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/amuled $(1)/usr/bin/amuled
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/amuleweb $(1)/usr/bin/amuleweb
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/amule $(1)/usr/share/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,amule))
|
1512
amule/patches/001_amule-dlp.patch
Normal file
1512
amule/patches/001_amule-dlp.patch
Normal file
File diff suppressed because it is too large
Load Diff
22
amule/patches/002_enable_upnp_cross_compile.patch
Normal file
22
amule/patches/002_enable_upnp_cross_compile.patch
Normal file
@ -0,0 +1,22 @@
|
||||
--- a/m4/libupnp.m4
|
||||
+++ b/m4/libupnp.m4
|
||||
@@ -57,7 +57,6 @@ dnl Test for --with-libupnp-prefix
|
||||
])
|
||||
|
||||
dnl Check for libupnp >= MIN_LIBUPNP_VERSION
|
||||
- AS_IF([test $cross_compiling = no], [
|
||||
AC_MSG_CHECKING([for libupnp version >= MIN_LIBUPNP_VERSION])
|
||||
AS_IF([test -n "$PKG_CONFIG"], [
|
||||
AS_IF([$PKG_CONFIG libupnp --exists], [
|
||||
@@ -84,11 +83,6 @@ dnl Check for libupnp >= MIN_LIBUPNP_VER
|
||||
])
|
||||
AC_MSG_RESULT([$result$resultstr])
|
||||
libupnp_error="libupnp >= MIN_LIBUPNP_VERSION not found$resultstr"
|
||||
- ], [
|
||||
-dnl Currently cross-compilation with libupnp is not supported.
|
||||
- result=no
|
||||
- libupnp_error="cross compiling"
|
||||
- ])
|
||||
|
||||
dnl Execute the right action.
|
||||
AS_IF([test ${result:-no} = yes], [$2], [$3])
|
83
aria2/Config.in
Normal file
83
aria2/Config.in
Normal file
@ -0,0 +1,83 @@
|
||||
menu "Aria2 Configuration"
|
||||
depends on PACKAGE_aria2
|
||||
|
||||
choice
|
||||
prompt "SSL Library"
|
||||
default ARIA2_OPENSSL
|
||||
|
||||
config ARIA2_OPENSSL
|
||||
bool "OpenSSL"
|
||||
|
||||
config ARIA2_GNUTLS
|
||||
bool "GnuTLS"
|
||||
|
||||
config ARIA2_NOSSL
|
||||
bool "No SSL Support"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "Crypto Library"
|
||||
depends on !ARIA2_OPENSSL
|
||||
default ARIA2_NOCRYPTO
|
||||
|
||||
config ARIA2_NETTLE
|
||||
bool "Nettle"
|
||||
|
||||
config ARIA2_LIBGCRYPT
|
||||
bool "Libgcrypt"
|
||||
|
||||
config ARIA2_NOCRYPTO
|
||||
bool "No Crypto Library"
|
||||
|
||||
endchoice
|
||||
|
||||
choice
|
||||
prompt "XML Library"
|
||||
default ARIA2_NOXML
|
||||
|
||||
config ARIA2_LIBXML2
|
||||
bool "Libxml2"
|
||||
|
||||
config ARIA2_EXPAT
|
||||
bool "Expat"
|
||||
|
||||
config ARIA2_NOXML
|
||||
bool "No XML Library"
|
||||
|
||||
endchoice
|
||||
|
||||
config ARIA2_GMP
|
||||
bool "GNU Multiple Precision Arithmetic Library"
|
||||
depends on ARIA2_NETTLE
|
||||
default n
|
||||
|
||||
config ARIA2_BITTORRENT
|
||||
bool "Enable Bittorrent Support"
|
||||
depends on ARIA2_OPENSSL || ARIA2_LIBGCRYPT || \
|
||||
(ARIA2_NETTLE && ARIA2_GMP)
|
||||
default y
|
||||
|
||||
config ARIA2_METALINK
|
||||
bool "Enable Metalink Support"
|
||||
depends on !ARIA2_NOXML
|
||||
default n
|
||||
|
||||
config ARIA2_SFTP
|
||||
bool "Enable SFTP Support"
|
||||
default n
|
||||
|
||||
config ARIA2_ASYNC_DNS
|
||||
bool "Enable Async DNS Support"
|
||||
default n
|
||||
|
||||
config ARIA2_COOKIE
|
||||
bool "Enable Firefox3/Chromium Cookie Support"
|
||||
default n
|
||||
|
||||
config ARIA2_WEBSOCKET
|
||||
bool "Enable JSON-RPC over WebSocket Support"
|
||||
depends on ARIA2_OPENSSL || ARIA2_LIBGCRYPT || ARIA2_NETTLE
|
||||
default y
|
||||
|
||||
endmenu
|
121
aria2/Makefile
Normal file
121
aria2/Makefile
Normal file
@ -0,0 +1,121 @@
|
||||
#
|
||||
# Copyright (C) 2012-2018 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=aria2
|
||||
PKG_VERSION:=1.36.0
|
||||
PKG_RELEASE:=9
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.xz
|
||||
PKG_SOURCE_URL:=https://github.com/aria2/aria2/releases/download/release-$(PKG_VERSION)/
|
||||
PKG_HASH:=skip
|
||||
PKG_INSTALL:=1
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
|
||||
PKG_MAINTAINER:=Imre Kaloz <kaloz@openwrt.org>, \
|
||||
Hsing-Wang Liao <kuoruan@gmail.com>
|
||||
PKG_LICENSE:=GPLv2
|
||||
PKG_LICENSE_FILES:=COPYING
|
||||
PKG_CPE_ID:=cpe:/a:tatsuhiro_tsujikawa:aria2
|
||||
|
||||
PKG_CONFIG_DEPENDS := \
|
||||
CONFIG_ARIA2_NOSSL \
|
||||
CONFIG_ARIA2_OPENSSL \
|
||||
CONFIG_ARIA2_GNUTLS \
|
||||
CONFIG_ARIA2_NOCRYPTO \
|
||||
CONFIG_ARIA2_NETTLE \
|
||||
CONFIG_ARIA2_LIBGCRYPT \
|
||||
CONFIG_ARIA2_LIBXML2 \
|
||||
CONFIG_ARIA2_EXPAT \
|
||||
CONFIG_ARIA2_GMP \
|
||||
CONFIG_ARIA2_BITTORRENT \
|
||||
CONFIG_ARIA2_METALINK \
|
||||
CONFIG_ARIA2_SFTP \
|
||||
CONFIG_ARIA2_ASYNC_DNS \
|
||||
CONFIG_ARIA2_COOKIE \
|
||||
CONFIG_ARIA2_WEBSOCKET
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/aria2/config
|
||||
source "$(SOURCE)/Config.in"
|
||||
endef
|
||||
|
||||
define Package/aria2
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
SUBMENU:=File Transfer
|
||||
TITLE:=lightweight download utility
|
||||
URL:=https://aria2.github.io/
|
||||
DEPENDS:=+zlib +libstdcpp +ARIA2_OPENSSL:libopenssl +ARIA2_GNUTLS:libgnutls \
|
||||
+ARIA2_NETTLE:libnettle +ARIA2_LIBGCRYPT:libgcrypt +ARIA2_GMP:libgmp \
|
||||
+ARIA2_LIBXML2:libxml2 +ARIA2_EXPAT:libexpat +ARIA2_SFTP:libssh2 \
|
||||
+ARIA2_ASYNC_DNS:libcares +ARIA2_COOKIE:libsqlite3
|
||||
USERID:=aria2=6800:aria2=6800
|
||||
endef
|
||||
|
||||
define Package/aria2/description
|
||||
aria2 is a lightweight multi-protocol & multi-source command-line download
|
||||
utility
|
||||
endef
|
||||
|
||||
CONFIGURE_ARGS += \
|
||||
--disable-nls \
|
||||
$(if $(CONFIG_ARIA2_NOSSL),--disable,--enable)-ssl \
|
||||
$(if $(CONFIG_ARIA2_BITTORRENT),--enable,--disable)-bittorrent \
|
||||
$(if $(CONFIG_ARIA2_METALINK),--enable,--disable)-metalink \
|
||||
$(if $(CONFIG_ARIA2_WEBSOCKET),--enable,--disable)-websocket \
|
||||
$(if $(CONFIG_ARIA2_OPENSSL),--with,--without)-openssl \
|
||||
$(if $(CONFIG_ARIA2_GNUTLS),--with,--without)-gnutls \
|
||||
$(if $(CONFIG_ARIA2_NETTLE),--with,--without)-libnettle \
|
||||
$(if $(CONFIG_ARIA2_LIBGCRYPT),--with,--without)-libgcrypt \
|
||||
$(if $(CONFIG_ARIA2_GMP),--with,--without)-libgmp \
|
||||
$(if $(CONFIG_ARIA2_LIBXML2),--with,--without)-libxml2 \
|
||||
$(if $(CONFIG_ARIA2_EXPAT),--with,--without)-libexpat \
|
||||
$(if $(CONFIG_ARIA2_SFTP),--with,--without)-libssh2 \
|
||||
$(if $(CONFIG_ARIA2_ASYNC_DNS),--with,--without)-libcares \
|
||||
$(if $(CONFIG_ARIA2_COOKIE),--with,--without)-sqlite3 \
|
||||
--without-libuv \
|
||||
--with-libz
|
||||
|
||||
TARGET_CXXFLAGS += -ffunction-sections -fdata-sections -flto
|
||||
TARGET_LDFLAGS += -Wl,--gc-sections -flto
|
||||
|
||||
define Package/aria2/conffiles
|
||||
/etc/config/aria2
|
||||
endef
|
||||
|
||||
define Download/aria2.conf
|
||||
URL:=https://github.com/P3TERX/aria2.conf/archive
|
||||
URL_FILE:=master.zip
|
||||
FILE:=aria2.conf
|
||||
HASH:=skip
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
$(call Build/Prepare/Default)
|
||||
unzip $(DL_DIR)/aria2.conf -d $(PKG_BUILD_DIR)/
|
||||
sed -i '/rpc-secret/d' $(PKG_BUILD_DIR)/aria2.conf-master/*
|
||||
endef
|
||||
|
||||
|
||||
define Package/aria2/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/aria2c $(1)/usr/bin
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/aria2.init $(1)/etc/init.d/aria2
|
||||
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_CONF) ./files/aria2.conf $(1)/etc/config/aria2
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/aria2
|
||||
$(INSTALL_BIN) $(PKG_BUILD_DIR)/aria2.conf-master/* $(1)/usr/share/aria2/
|
||||
endef
|
||||
|
||||
$(eval $(call Download,aria2.conf))
|
||||
$(eval $(call BuildPackage,aria2))
|
23
aria2/files/aria2.conf
Normal file
23
aria2/files/aria2.conf
Normal file
@ -0,0 +1,23 @@
|
||||
|
||||
# You can use most aria2 command-line options, replace '-' with '_'.
|
||||
# eg. 'rpc-secret' ==> 'rpc_secret'
|
||||
#
|
||||
# We do not support all options at this time. But you can add any option
|
||||
# with 'list extra_settings'.
|
||||
#
|
||||
# You can also add new config sections to define multi instance.
|
||||
#
|
||||
config aria2 'main'
|
||||
option enabled '0'
|
||||
option user 'aria2'
|
||||
option dir '/mnt/sda1/aria2'
|
||||
option config_dir '/var/etc/aria2'
|
||||
option bt_enable_lpd 'true'
|
||||
option enable_dht 'true'
|
||||
option follow_torrent 'true'
|
||||
option file_allocation 'none'
|
||||
option save_session_interval '30'
|
||||
option split '128'
|
||||
option min_split_size '100K'
|
||||
option max_connection_per_server '128'
|
||||
list extra_settings 'dht-file-path=/usr/share/aria2/dht.dat'
|
360
aria2/files/aria2.init
Normal file
360
aria2/files/aria2.init
Normal file
@ -0,0 +1,360 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2016-2017 Hsing-wang Liao <kuoruan@gmail.com>
|
||||
# Licensed to the public under the Apache License 2.0.
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
NAME=aria2
|
||||
PROG=/usr/bin/aria2c
|
||||
|
||||
_info() {
|
||||
logger -p daemon.info -t "$NAME" "$*"
|
||||
}
|
||||
|
||||
_err() {
|
||||
logger -p daemon.err -t "$NAME" "$*"
|
||||
}
|
||||
|
||||
_make_dir() {
|
||||
local d
|
||||
for d in "$@"; do
|
||||
if [ ! -d "$d" ]; then
|
||||
mkdir -p "$d" 2>/dev/null || return 1
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_create_file() {
|
||||
touch "$@" 2>/dev/null
|
||||
}
|
||||
|
||||
_change_owner() {
|
||||
local u="$1"; shift
|
||||
|
||||
local d
|
||||
for d in "$@"; do
|
||||
if [ -f "$d" ]; then
|
||||
chown "$u" "$d" 2>/dev/null || return 1
|
||||
elif [ -d "$d" ]; then
|
||||
chown -R "$u" "$d" 2>/dev/null || return 1
|
||||
fi
|
||||
done
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
_change_file_mode() {
|
||||
local mod="$1"; shift
|
||||
chmod "$mod" "$@" 2>/dev/null
|
||||
}
|
||||
|
||||
_reset_dir_mode() {
|
||||
local d
|
||||
for d in "$@"; do
|
||||
if [ -d "$d" ]; then
|
||||
find "$d" -type d -exec chmod 755 {} \; 2>/dev/null
|
||||
find "$d" -type f -exec chmod 644 {} \; 2>/dev/null
|
||||
fi
|
||||
done
|
||||
}
|
||||
|
||||
append_options() {
|
||||
local o; local v
|
||||
for o in "$@"; do
|
||||
v="$(eval echo "\$$o")"
|
||||
[ -n "$v" ] && \
|
||||
echo "${o//_/-}=$v" >>"$config_file_tmp"
|
||||
done
|
||||
}
|
||||
|
||||
append_setting() {
|
||||
local s="$1"
|
||||
[ -n "$s" ] && \
|
||||
echo "$s" >>"$config_file_tmp"
|
||||
}
|
||||
|
||||
append_header() {
|
||||
local h="$1"
|
||||
[ -n "$h" ] && \
|
||||
echo "header=\"$h\"" >>"$config_file_tmp"
|
||||
}
|
||||
|
||||
aria2_validate() {
|
||||
uci_load_validate "$NAME" aria2 "$1" "$2" \
|
||||
'enabled:bool:0' \
|
||||
'enable_logging:bool' \
|
||||
'enable_proxy:bool' \
|
||||
'config_dir:string:/var/etc/aria2' \
|
||||
'user:string' \
|
||||
'all_proxy:string' \
|
||||
'all_proxy_passwd:string' \
|
||||
'all_proxy_user:string' \
|
||||
'auto_save_interval:range(0,600)' \
|
||||
'bt_enable_lpd:or("true","false")' \
|
||||
'bt_detach_seed_only:or("true","false")' \
|
||||
'bt_load_saved_metadata:or("true","false")' \
|
||||
'bt_prioritize_piece:string' \
|
||||
'bt_max_open_files:uinteger' \
|
||||
'bt_max_peers:uinteger' \
|
||||
'bt_remove_unselected_file:or("true","false")' \
|
||||
'bt_request_peer_speed_limit:string' \
|
||||
'bt_save_metadata:or("true","false")' \
|
||||
'bt_seed_unverified:or("true","false")' \
|
||||
'bt_stop_timeout:uinteger' \
|
||||
'bt_tracker:list(string)' \
|
||||
'ca_certificate:file' \
|
||||
'certificate:file' \
|
||||
'check_certificate:or("true","false"):true' \
|
||||
'check_integrity:or("true","false")' \
|
||||
'connect_timeout:uinteger' \
|
||||
'dht_listen_port:string' \
|
||||
'dir:string' \
|
||||
'disable_ipv6:or("true","false")' \
|
||||
'disk_cache:string' \
|
||||
'enable_dht:or("true","false"):true' \
|
||||
'enable_dht6:or("true","false")' \
|
||||
'enable_peer_exchange:or("true","false")' \
|
||||
'event_poll:or("epoll","kqueue","port","poll","select")' \
|
||||
'file_allocation:or("none","prealloc","trunc","falloc")' \
|
||||
'follow_torrent:or("true","false","mem")' \
|
||||
'force_save:or("true","false")' \
|
||||
'http_accept_gzip:or("true","false")' \
|
||||
'http_no_cache:or("true","false")' \
|
||||
'listen_port:string' \
|
||||
'log:string' \
|
||||
'log_level:or("debug","info","notice","warn","error")' \
|
||||
'lowest_speed_limit:string' \
|
||||
'max_concurrent_downloads:uinteger' \
|
||||
'max_connection_per_server:uinteger' \
|
||||
'max_download_limit:string' \
|
||||
'max_overall_download_limit:string' \
|
||||
'max_overall_upload_limit:string' \
|
||||
'max_tries:uinteger' \
|
||||
'max_upload_limit:string' \
|
||||
'min_split_size:string' \
|
||||
'pause:or("true","false")' \
|
||||
'pause_metadata:or("true","false")' \
|
||||
'peer_id_prefix:string' \
|
||||
'private_key:file' \
|
||||
'retry_wait:uinteger' \
|
||||
'rpc_auth_method:or("none","user_pass","token")' \
|
||||
'rpc_certificate:file' \
|
||||
'rpc_listen_port:range(1024,65535)' \
|
||||
'rpc_passwd:string' \
|
||||
'rpc_private_key:file' \
|
||||
'rpc_secret:string' \
|
||||
'rpc_secure:or("true","false")' \
|
||||
'rpc_user:string' \
|
||||
'save_session_interval:uinteger' \
|
||||
'seed_ratio:ufloat' \
|
||||
'seed_time:ufloat' \
|
||||
'split:uinteger' \
|
||||
'timeout:uinteger' \
|
||||
'user_agent:string'
|
||||
}
|
||||
|
||||
aria2_start() {
|
||||
local section="$1"
|
||||
[ "$2" = "0" ] || { _err "Validation failed."; return 1; }
|
||||
|
||||
[ "$enabled" = "1" ] || { _info "Instance \"$section\" disabled."; return 1; }
|
||||
[ -n "$dir" ] || { _err "Please set download dir."; return 1; }
|
||||
[ -d "$dir" ] || { _err "Please create download dir first."; return 1; }
|
||||
|
||||
config_file="$config_dir/$NAME.conf.$section"
|
||||
config_file_tmp="$config_dir/$NAME.conf.tmp"
|
||||
session_file="$config_dir/$NAME.session.$section"
|
||||
|
||||
_make_dir "$config_dir" || {
|
||||
_err "Can't create config dir: $config_dir"
|
||||
return 1
|
||||
}
|
||||
|
||||
_create_file "$session_file" "$config_file" "$config_file_tmp" || {
|
||||
_err "Can't create files: $session_file, $config_file, $config_file_tmp"
|
||||
return 1
|
||||
}
|
||||
|
||||
# create tmp file
|
||||
cat >"$config_file_tmp" <<-EOF
|
||||
# Auto generated file, changes to this file will be lost.
|
||||
EOF
|
||||
|
||||
append_setting "dir=$dir"
|
||||
append_setting "enable-rpc=true"
|
||||
append_setting "rpc-allow-origin-all=true"
|
||||
append_setting "rpc-listen-all=true"
|
||||
append_setting "quiet=true"
|
||||
append_setting "continue=true"
|
||||
append_setting "input-file=$session_file"
|
||||
append_setting "save-session=$session_file"
|
||||
|
||||
if [ -z "$enable_logging" ]; then
|
||||
append_options "log" "log_level"
|
||||
elif [ "$enable_logging" = "1" ]; then
|
||||
log=${log:-"/var/log/aria2.log"}
|
||||
|
||||
local log_dir
|
||||
log_dir="$(dirname "$log")"
|
||||
|
||||
_make_dir "$log_dir" || {
|
||||
_err "Can't create log dir: $log_dir"
|
||||
return 1
|
||||
}
|
||||
|
||||
# create or clear log file
|
||||
echo >"$log"
|
||||
|
||||
append_setting "log=$log"
|
||||
append_options "log_level"
|
||||
fi
|
||||
|
||||
if [ -z "$enable_proxy" ] || [ "$enable_proxy" = "1" ]; then
|
||||
append_options "all_proxy" "all_proxy_user" "all_proxy_passwd"
|
||||
fi
|
||||
|
||||
unset_auth_method() {
|
||||
uci -q batch <<-EOF
|
||||
set $NAME.$section.rpc_auth_method=""
|
||||
commit $NAME
|
||||
EOF
|
||||
}
|
||||
|
||||
if [ -z "$rpc_auth_method" ]; then
|
||||
if [ -n "$rpc_secret" ]; then
|
||||
append_setting "rpc-secret=$rpc_secret"
|
||||
elif [ -n "$rpc_user" ]; then
|
||||
append_setting "rpc-user=$rpc_user"
|
||||
append_setting "rpc-passwd=$rpc_passwd"
|
||||
else
|
||||
_info "It is recommended to set RPC secret."
|
||||
fi
|
||||
elif [ "$rpc_auth_method" = "token" ]; then
|
||||
if [ -n "$rpc_secret" ]; then
|
||||
append_setting "rpc-secret=$rpc_secret"
|
||||
else
|
||||
unset_auth_method
|
||||
fi
|
||||
elif [ "$rpc_auth_method" = "user_pass" ]; then
|
||||
if [ -n "$rpc_user" ]; then
|
||||
append_setting "rpc-user=$rpc_user"
|
||||
append_setting "rpc-passwd=$rpc_passwd"
|
||||
else
|
||||
_info "Please set RPC user."
|
||||
unset_auth_method
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ ."$rpc_secure" = ."true" ] && [ -n "$rpc_certificate" ]; then
|
||||
append_setting "rpc-secure=true"
|
||||
append_options "rpc_certificate" "rpc_private_key"
|
||||
fi
|
||||
|
||||
if [ ."$check_certificate" = ."true" ]; then
|
||||
append_setting "check-certificate=true"
|
||||
append_options "ca_certificate"
|
||||
elif [ ."$check_certificate" = ."false" ]; then
|
||||
append_setting "check-certificate=false"
|
||||
fi
|
||||
|
||||
if [ ."$enable_dht" = ."true" ]; then
|
||||
dht_file="$config_dir/dht.dat.$section"
|
||||
_create_file "$dht_file" || {
|
||||
_err "Can't create DHT file: $dht_file"
|
||||
return 1
|
||||
}
|
||||
|
||||
append_setting "enable-dht=true"
|
||||
append_setting "dht-file-path=$dht_file"
|
||||
fi
|
||||
|
||||
if [ ."$enable_dht6" = ."true" ] && [ ."$disable_ipv6" != ."true" ]; then
|
||||
dht6_file="$config_dir/dht6.dat.$section"
|
||||
_create_file "$dht6_file" || {
|
||||
_err "Can't create DHT6 file: $dht6_file"
|
||||
return 1
|
||||
}
|
||||
|
||||
append_setting "enable-dht6=true"
|
||||
append_setting "dht-file-path6=$dht6_file"
|
||||
fi
|
||||
|
||||
if [ -n "$bt_tracker" ]; then
|
||||
local bt_tracker_list; local t
|
||||
for t in $bt_tracker; do
|
||||
if [ -z "$bt_tracker_list" ]; then
|
||||
bt_tracker_list="$t"
|
||||
else
|
||||
bt_tracker_list="$bt_tracker_list,$t"
|
||||
fi
|
||||
done
|
||||
|
||||
append_setting "bt-tracker=$bt_tracker_list"
|
||||
fi
|
||||
|
||||
append_options "auto_save_interval" "bt_enable_lpd" "bt_max_open_files" "bt_max_peers" \
|
||||
"bt_remove_unselected_file" "bt_request_peer_speed_limit" "bt_prioritize_piece" \
|
||||
"bt_stop_timeout" "bt_detach_seed_only" "bt_save_metadata" "bt_load_saved_metadata" \
|
||||
"bt_seed_unverified" "certificate" "check_integrity" "connect_timeout" "dht_listen_port" \
|
||||
"disable_ipv6" "disk_cache" "enable_peer_exchange" "event_poll" "file_allocation" \
|
||||
"follow_torrent" "force_save" "http_accept_gzip" "http_no_cache" "listen_port" \
|
||||
"lowest_speed_limit" "max_concurrent_downloads" "max_connection_per_server" \
|
||||
"max_download_limit" "max_overall_download_limit" "max_overall_upload_limit" "max_tries" \
|
||||
"max_upload_limit" "min_split_size" "pause" "pause_metadata" "peer_id_prefix" "private_key" \
|
||||
"retry_wait" "rpc_listen_port" "save_session_interval" "seed_ratio" "seed_time" "split" "timeout" \
|
||||
"user_agent"
|
||||
|
||||
config_list_foreach "$section" "header" append_header
|
||||
config_list_foreach "$section" "extra_settings" append_setting
|
||||
|
||||
cd /usr/share/aria2 && sh ./tracker.sh
|
||||
cat /usr/share/aria2/aria2.conf > "$config_file"
|
||||
echo '' >> "$config_file"
|
||||
sed '/^$/d' "$config_file_tmp" >> "$config_file"
|
||||
rm -f "$config_file_tmp"
|
||||
|
||||
_reset_dir_mode "$config_dir"
|
||||
_change_file_mode 600 "$config_file"
|
||||
|
||||
if [ -n "$user" ]; then
|
||||
if ( user_exists "$user" && _change_owner "$user" "$config_dir" "$log" ); then
|
||||
_info "Aria2 will run with user '$user'."
|
||||
if [ "$user" != "root" ]; then
|
||||
_info "Please make sure user '$user' has write access to download dir: $dir"
|
||||
fi
|
||||
else
|
||||
_info "Setting run user to '$user' failed, default user will be used."
|
||||
user=
|
||||
fi
|
||||
fi
|
||||
|
||||
procd_open_instance "$NAME.$section"
|
||||
procd_set_param command "$PROG"
|
||||
procd_append_param command --conf-path="$config_file"
|
||||
|
||||
procd_set_param respawn
|
||||
procd_set_param stdout 1
|
||||
procd_set_param stderr 1
|
||||
|
||||
procd_set_param file "$config_file"
|
||||
[ -n "$user" ] && \
|
||||
procd_set_param user "$user"
|
||||
|
||||
procd_add_jail "$NAME.$section" log
|
||||
procd_add_jail_mount "$config_file"
|
||||
procd_add_jail_mount_rw "$dir" "$config_dir" "$log"
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger "$NAME"
|
||||
procd_add_validation aria2_validate
|
||||
}
|
||||
|
||||
start_service() {
|
||||
config_load "$NAME"
|
||||
config_foreach aria2_validate "aria2" aria2_start
|
||||
}
|
@ -0,0 +1,29 @@
|
||||
--- /src/OptionHandlerFactory.cc 2018-05-15 20:33:25.000000000 +0800
|
||||
+++ /src/OptionHandlerFactory.cc 2018-07-05 10:40:25.000000000 +0800
|
||||
@@ -440,7 +440,7 @@
|
||||
{
|
||||
OptionHandler* op(new NumberOptionHandler(PREF_MAX_CONNECTION_PER_SERVER,
|
||||
TEXT_MAX_CONNECTION_PER_SERVER,
|
||||
- "1", 1, 16, 'x'));
|
||||
+ "64", 1, -1, 'x'));
|
||||
op->addTag(TAG_BASIC);
|
||||
op->addTag(TAG_FTP);
|
||||
op->addTag(TAG_HTTP);
|
||||
@@ -501,7 +501,7 @@
|
||||
}
|
||||
{
|
||||
OptionHandler* op(new UnitNumberOptionHandler(
|
||||
- PREF_MIN_SPLIT_SIZE, TEXT_MIN_SPLIT_SIZE, "20M", 1_m, 1_g, 'k'));
|
||||
+ PREF_MIN_SPLIT_SIZE, TEXT_MIN_SPLIT_SIZE, "1M", 1_k, 1_g, 'k'));
|
||||
op->addTag(TAG_BASIC);
|
||||
op->addTag(TAG_FTP);
|
||||
op->addTag(TAG_HTTP);
|
||||
@@ -905,7 +905,7 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
||||
}
|
||||
{
|
||||
OptionHandler* op(new UnitNumberOptionHandler(
|
||||
- PREF_PIECE_LENGTH, TEXT_PIECE_LENGTH, "1M", 1_m, 1_g));
|
||||
+ PREF_PIECE_LENGTH, TEXT_PIECE_LENGTH, "1M", 1_k, 1_g));
|
||||
op->addTag(TAG_ADVANCED);
|
||||
op->addTag(TAG_FTP);
|
||||
op->addTag(TAG_HTTP);
|
@ -0,0 +1,61 @@
|
||||
From 66524bee738e98742c908d93c993d0a78a2d9891 Mon Sep 17 00:00:00 2001
|
||||
From: myfreeer <myfreeer@users.noreply.github.com>
|
||||
Date: Sat, 18 Nov 2017 11:55:04 +0800
|
||||
Subject: [PATCH 3/4] download: retry on slow speed and conection close
|
||||
|
||||
This would provide better speed on bad network conditions
|
||||
---
|
||||
src/DownloadCommand.cc | 2 +-
|
||||
src/SocketBuffer.cc | 3 ++-
|
||||
src/SocketCore.cc | 2 +-
|
||||
3 files changed, 4 insertions(+), 3 deletions(-)
|
||||
|
||||
diff --git a/src/DownloadCommand.cc b/src/DownloadCommand.cc
|
||||
index 2db41e4..f49eb80 100644
|
||||
--- a/src/DownloadCommand.cc
|
||||
+++ b/src/DownloadCommand.cc
|
||||
@@ -306,7 +306,7 @@ void DownloadCommand::checkLowestDownloadSpeed() const
|
||||
startupIdleTime_) {
|
||||
int nowSpeed = peerStat_->calculateDownloadSpeed();
|
||||
if (nowSpeed <= lowestDownloadSpeedLimit_) {
|
||||
- throw DL_ABORT_EX2(fmt(EX_TOO_SLOW_DOWNLOAD_SPEED, nowSpeed,
|
||||
+ throw DL_RETRY_EX2(fmt(EX_TOO_SLOW_DOWNLOAD_SPEED, nowSpeed,
|
||||
lowestDownloadSpeedLimit_,
|
||||
getRequest()->getHost().c_str()),
|
||||
error_code::TOO_SLOW_DOWNLOAD_SPEED);
|
||||
diff --git a/src/SocketBuffer.cc b/src/SocketBuffer.cc
|
||||
index 62862ff..1906173 100644
|
||||
--- a/src/SocketBuffer.cc
|
||||
+++ b/src/SocketBuffer.cc
|
||||
@@ -39,6 +39,7 @@
|
||||
|
||||
#include "SocketCore.h"
|
||||
#include "DlAbortEx.h"
|
||||
+#include "DlRetryEx.h"
|
||||
#include "message.h"
|
||||
#include "fmt.h"
|
||||
#include "LogFactory.h"
|
||||
@@ -158,7 +159,7 @@ ssize_t SocketBuffer::send()
|
||||
}
|
||||
ssize_t slen = socket_->writeVector(iov, num);
|
||||
if (slen == 0 && !socket_->wantRead() && !socket_->wantWrite()) {
|
||||
- throw DL_ABORT_EX(fmt(EX_SOCKET_SEND, "Connection closed."));
|
||||
+ throw DL_RETRY_EX(fmt(EX_SOCKET_SEND, "Connection closed."));
|
||||
}
|
||||
// A2_LOG_NOTICE(fmt("num=%zu, amount=%d, bufq.size()=%zu, SEND=%d",
|
||||
// num, amount, bufq_.size(), slen));
|
||||
diff --git a/src/SocketCore.cc b/src/SocketCore.cc
|
||||
index 77dc30c..537375a 100644
|
||||
--- a/src/SocketCore.cc
|
||||
+++ b/src/SocketCore.cc
|
||||
@@ -1009,7 +1009,7 @@ bool SocketCore::tlsHandshake(TLSContext* tlsctx, const std::string& hostname)
|
||||
|
||||
if (rv == TLS_ERR_ERROR) {
|
||||
// Damn those error.
|
||||
- throw DL_ABORT_EX(fmt("SSL/TLS handshake failure: %s",
|
||||
+ throw DL_RETRY_EX(fmt("SSL/TLS handshake failure: %s",
|
||||
handshakeError.empty()
|
||||
? tlsSession_->getLastErrorString().c_str()
|
||||
: handshakeError.c_str()));
|
||||
--
|
||||
2.17.1
|
239
aria2/patches/0003-option-add-option-to-retry-on-http-4xx.patch
Normal file
239
aria2/patches/0003-option-add-option-to-retry-on-http-4xx.patch
Normal file
@ -0,0 +1,239 @@
|
||||
From 8adbc01dc5975a64c55fe594d8c758c71e8183b3 Mon Sep 17 00:00:00 2001
|
||||
From: myfreeer <myfreeer@users.noreply.github.com>
|
||||
Date: Sun, 22 Jul 2018 19:59:02 +0800
|
||||
Subject: [PATCH] option: add option to retry on http 400, 403, 406, or unknown
|
||||
|
||||
--retry-on-400[=true|false] Configure whether retry or not when
|
||||
HTTP server returns 400 Bad Request.
|
||||
Only effective if retry-wait > 0.
|
||||
|
||||
Possible Values: true, false
|
||||
Default: false
|
||||
Tags: #advanced, #http
|
||||
|
||||
--retry-on-403[=true|false] Configure whether retry or not when
|
||||
HTTP server returns 403 Forbidden.
|
||||
Only effective if retry-wait > 0.
|
||||
|
||||
Possible Values: true, false
|
||||
Default: false
|
||||
Tags: #advanced, #http
|
||||
|
||||
--retry-on-406[=true|false] Configure whether retry or not when
|
||||
HTTP server returns 406 Not Acceptable.
|
||||
Only effective if retry-wait > 0.
|
||||
|
||||
Possible Values: true, false
|
||||
Default: false
|
||||
Tags: #advanced, #http
|
||||
|
||||
--retry-on-unknown[=true|false] Configure whether retry or not when
|
||||
HTTP server returns unknown status code.
|
||||
Only effective if retry-wait > 0.
|
||||
|
||||
Possible Values: true, false
|
||||
Default: false
|
||||
Tags: #advanced, #http
|
||||
---
|
||||
src/HttpSkipResponseCommand.cc | 42 +++++++++++++++++++++++++++++-----
|
||||
src/OptionHandlerFactory.cc | 40 ++++++++++++++++++++++++++++++++
|
||||
src/prefs.cc | 8 +++++++
|
||||
src/prefs.h | 8 +++++++
|
||||
src/usage_text.h | 16 +++++++++++++
|
||||
5 files changed, 108 insertions(+), 6 deletions(-)
|
||||
|
||||
diff --git a/src/HttpSkipResponseCommand.cc b/src/HttpSkipResponseCommand.cc
|
||||
index a722d77..de4ad6c 100644
|
||||
--- a/src/HttpSkipResponseCommand.cc
|
||||
+++ b/src/HttpSkipResponseCommand.cc
|
||||
@@ -204,7 +204,7 @@ bool HttpSkipResponseCommand::processResponse()
|
||||
auto statusCode = httpResponse_->getStatusCode();
|
||||
if (statusCode >= 400) {
|
||||
switch (statusCode) {
|
||||
- case 401:
|
||||
+ case 401: // Unauthorized
|
||||
if (getOption()->getAsBool(PREF_HTTP_AUTH_CHALLENGE) &&
|
||||
!httpResponse_->getHttpRequest()->authenticationUsed() &&
|
||||
getDownloadEngine()->getAuthConfigFactory()->activateBasicCred(
|
||||
@@ -213,15 +213,41 @@ bool HttpSkipResponseCommand::processResponse()
|
||||
return prepareForRetry(0);
|
||||
}
|
||||
throw DL_ABORT_EX2(EX_AUTH_FAILED, error_code::HTTP_AUTH_FAILED);
|
||||
- case 404:
|
||||
+ case 404: // Not Found
|
||||
if (getOption()->getAsInt(PREF_MAX_FILE_NOT_FOUND) == 0) {
|
||||
throw DL_ABORT_EX2(MSG_RESOURCE_NOT_FOUND,
|
||||
error_code::RESOURCE_NOT_FOUND);
|
||||
}
|
||||
throw DL_RETRY_EX2(MSG_RESOURCE_NOT_FOUND,
|
||||
error_code::RESOURCE_NOT_FOUND);
|
||||
- case 502:
|
||||
- case 503:
|
||||
+ case 400: // Bad Request
|
||||
+ if (getOption()->getAsBool(PREF_RETRY_ON_400)
|
||||
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
||||
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
||||
+ error_code::HTTP_PROTOCOL_ERROR);
|
||||
+ }
|
||||
+ break;
|
||||
+ case 403: // Forbidden
|
||||
+ if (getOption()->getAsBool(PREF_RETRY_ON_403)
|
||||
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
||||
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
||||
+ error_code::HTTP_PROTOCOL_ERROR);
|
||||
+ }
|
||||
+ break;
|
||||
+ case 406: // Not Acceptable
|
||||
+ if (getOption()->getAsBool(PREF_RETRY_ON_406)
|
||||
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
||||
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
||||
+ error_code::HTTP_PROTOCOL_ERROR);
|
||||
+ }
|
||||
+ break;
|
||||
+ case 408: // Request Timeout
|
||||
+ case 429: // Too Many Requests
|
||||
+ case 502: // Bad Gateway
|
||||
+ case 503: // Service Unavailable
|
||||
+ case 507: // Insufficient Storage
|
||||
+ case 520: // https://github.com/aria2/aria2/issues/1229
|
||||
+ case 521: // https://github.com/aria2/aria2/issues/1229
|
||||
// Only retry if pretry-wait > 0. Hammering 'busy' server is not
|
||||
// a good idea.
|
||||
if (getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
||||
@@ -230,12 +256,16 @@ bool HttpSkipResponseCommand::processResponse()
|
||||
}
|
||||
throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, statusCode),
|
||||
error_code::HTTP_SERVICE_UNAVAILABLE);
|
||||
- case 504:
|
||||
+ case 504: // Gateway Timeout
|
||||
// This is Gateway Timeout, so try again
|
||||
throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
||||
error_code::HTTP_SERVICE_UNAVAILABLE);
|
||||
};
|
||||
-
|
||||
+ if (getOption()->getAsBool(PREF_RETRY_ON_UNKNOWN)
|
||||
+ && getOption()->getAsInt(PREF_RETRY_WAIT) > 0) {
|
||||
+ throw DL_RETRY_EX2(fmt(EX_BAD_STATUS, statusCode),
|
||||
+ error_code::HTTP_PROTOCOL_ERROR);
|
||||
+ }
|
||||
throw DL_ABORT_EX2(fmt(EX_BAD_STATUS, statusCode),
|
||||
error_code::HTTP_PROTOCOL_ERROR);
|
||||
}
|
||||
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
|
||||
index 5768f7b..decb03e 100644
|
||||
--- a/src/OptionHandlerFactory.cc
|
||||
+++ b/src/OptionHandlerFactory.cc
|
||||
@@ -934,6 +934,46 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
||||
op->setChangeOptionForReserved(true);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
+ {
|
||||
+ OptionHandler* op(new BooleanOptionHandler(
|
||||
+ PREF_RETRY_ON_400, TEXT_RETRY_ON_400, A2_V_FALSE, OptionHandler::OPT_ARG));
|
||||
+ op->addTag(TAG_ADVANCED);
|
||||
+ op->addTag(TAG_HTTP);
|
||||
+ op->setInitialOption(true);
|
||||
+ op->setChangeGlobalOption(true);
|
||||
+ op->setChangeOptionForReserved(true);
|
||||
+ handlers.push_back(op);
|
||||
+ }
|
||||
+ {
|
||||
+ OptionHandler* op(new BooleanOptionHandler(
|
||||
+ PREF_RETRY_ON_403, TEXT_RETRY_ON_403, A2_V_FALSE, OptionHandler::OPT_ARG));
|
||||
+ op->addTag(TAG_ADVANCED);
|
||||
+ op->addTag(TAG_HTTP);
|
||||
+ op->setInitialOption(true);
|
||||
+ op->setChangeGlobalOption(true);
|
||||
+ op->setChangeOptionForReserved(true);
|
||||
+ handlers.push_back(op);
|
||||
+ }
|
||||
+ {
|
||||
+ OptionHandler* op(new BooleanOptionHandler(
|
||||
+ PREF_RETRY_ON_406, TEXT_RETRY_ON_406, A2_V_FALSE, OptionHandler::OPT_ARG));
|
||||
+ op->addTag(TAG_ADVANCED);
|
||||
+ op->addTag(TAG_HTTP);
|
||||
+ op->setInitialOption(true);
|
||||
+ op->setChangeGlobalOption(true);
|
||||
+ op->setChangeOptionForReserved(true);
|
||||
+ handlers.push_back(op);
|
||||
+ }
|
||||
+ {
|
||||
+ OptionHandler* op(new BooleanOptionHandler(
|
||||
+ PREF_RETRY_ON_UNKNOWN, TEXT_RETRY_ON_UNKNOWN, A2_V_FALSE, OptionHandler::OPT_ARG));
|
||||
+ op->addTag(TAG_ADVANCED);
|
||||
+ op->addTag(TAG_HTTP);
|
||||
+ op->setInitialOption(true);
|
||||
+ op->setChangeGlobalOption(true);
|
||||
+ op->setChangeOptionForReserved(true);
|
||||
+ handlers.push_back(op);
|
||||
+ }
|
||||
{
|
||||
OptionHandler* op(new BooleanOptionHandler(
|
||||
PREF_REUSE_URI, TEXT_REUSE_URI, A2_V_TRUE, OptionHandler::OPT_ARG));
|
||||
diff --git a/src/prefs.cc b/src/prefs.cc
|
||||
index 937e927..33eff91 100644
|
||||
--- a/src/prefs.cc
|
||||
+++ b/src/prefs.cc
|
||||
@@ -327,6 +327,14 @@ PrefPtr PREF_ENABLE_ASYNC_DNS6 = makePref("enable-async-dns6");
|
||||
PrefPtr PREF_MAX_DOWNLOAD_RESULT = makePref("max-download-result");
|
||||
// value: 1*digit
|
||||
PrefPtr PREF_RETRY_WAIT = makePref("retry-wait");
|
||||
+// value: true | false
|
||||
+PrefPtr PREF_RETRY_ON_400 = makePref("retry-on-400");
|
||||
+// value: true | false
|
||||
+PrefPtr PREF_RETRY_ON_403 = makePref("retry-on-403");
|
||||
+// value: true | false
|
||||
+PrefPtr PREF_RETRY_ON_406 = makePref("retry-on-406");
|
||||
+// value: true | false
|
||||
+PrefPtr PREF_RETRY_ON_UNKNOWN = makePref("retry-on-unknown");
|
||||
// value: string
|
||||
PrefPtr PREF_ASYNC_DNS_SERVER = makePref("async-dns-server");
|
||||
// value: true | false
|
||||
diff --git a/src/prefs.h b/src/prefs.h
|
||||
index e1f8397..019e774 100644
|
||||
--- a/src/prefs.h
|
||||
+++ b/src/prefs.h
|
||||
@@ -280,6 +280,14 @@ extern PrefPtr PREF_ENABLE_ASYNC_DNS6;
|
||||
extern PrefPtr PREF_MAX_DOWNLOAD_RESULT;
|
||||
// value: 1*digit
|
||||
extern PrefPtr PREF_RETRY_WAIT;
|
||||
+// value: true | false
|
||||
+extern PrefPtr PREF_RETRY_ON_400;
|
||||
+// value: true | false
|
||||
+extern PrefPtr PREF_RETRY_ON_403;
|
||||
+// value: true | false
|
||||
+extern PrefPtr PREF_RETRY_ON_406;
|
||||
+// value: true | false
|
||||
+extern PrefPtr PREF_RETRY_ON_UNKNOWN;
|
||||
// value: string
|
||||
extern PrefPtr PREF_ASYNC_DNS_SERVER;
|
||||
// value: true | false
|
||||
diff --git a/src/usage_text.h b/src/usage_text.h
|
||||
index d73b50d..75d34a0 100644
|
||||
--- a/src/usage_text.h
|
||||
+++ b/src/usage_text.h
|
||||
@@ -64,6 +64,22 @@
|
||||
_(" --retry-wait=SEC Set the seconds to wait between retries. \n" \
|
||||
" With SEC > 0, aria2 will retry download when the\n" \
|
||||
" HTTP server returns 503 response.")
|
||||
+#define TEXT_RETRY_ON_400 \
|
||||
+ _(" --retry-on-400[=true|false] Configure whether retry or not when\n" \
|
||||
+ " HTTP server returns 400 Bad Request.\n" \
|
||||
+ " Only effective if retry-wait > 0.")
|
||||
+#define TEXT_RETRY_ON_403 \
|
||||
+ _(" --retry-on-403[=true|false] Configure whether retry or not when\n" \
|
||||
+ " HTTP server returns 403 Forbidden.\n" \
|
||||
+ " Only effective if retry-wait > 0.")
|
||||
+#define TEXT_RETRY_ON_406 \
|
||||
+ _(" --retry-on-406[=true|false] Configure whether retry or not when\n" \
|
||||
+ " HTTP server returns 406 Not Acceptable.\n" \
|
||||
+ " Only effective if retry-wait > 0.")
|
||||
+#define TEXT_RETRY_ON_UNKNOWN \
|
||||
+ _(" --retry-on-unknown[=true|false] Configure whether retry or not when\n" \
|
||||
+ " HTTP server returns unknown status code.\n" \
|
||||
+ " Only effective if retry-wait > 0.")
|
||||
#define TEXT_TIMEOUT \
|
||||
_(" -t, --timeout=SEC Set timeout in seconds.")
|
||||
#define TEXT_MAX_TRIES \
|
||||
--
|
||||
2.18.0
|
123
aria2/patches/0004-Disable-auto-added-Want-Digest-header.patch
Normal file
123
aria2/patches/0004-Disable-auto-added-Want-Digest-header.patch
Normal file
@ -0,0 +1,123 @@
|
||||
From b938aa51e50852d1b185db3188357073ad374416 Mon Sep 17 00:00:00 2001
|
||||
From: myfreeer <myfreeer@users.noreply.github.com>
|
||||
Date: Sun, 13 Dec 2020 15:40:56 +0800
|
||||
Subject: [PATCH] option: add option to disable Want-Digest header
|
||||
|
||||
Sending this HTTP header should be optional.
|
||||
Should close https://github.com/myfreeer/aria2-build-msys2/issues/10
|
||||
|
||||
--http-want-digest[=true|false] Send Want-Digest HTTP requser header
|
||||
with only limited hash algorithms:
|
||||
SHA-512, SHA-256, and SHA-1.
|
||||
The Want-Digest HTTP header is primarily used
|
||||
in a HTTP request, to ask the responder to
|
||||
provide a digest of the requested resource
|
||||
using the Digest response header
|
||||
|
||||
Possible Values: true, false
|
||||
Default: false
|
||||
Tags: #advanced, #http
|
||||
---
|
||||
src/AbstractProxyRequestCommand.cc | 1 +
|
||||
src/HttpRequestCommand.cc | 1 +
|
||||
src/OptionHandlerFactory.cc | 12 ++++++++++++
|
||||
src/prefs.cc | 2 ++
|
||||
src/prefs.h | 2 ++
|
||||
src/usage_text.h | 8 ++++++++
|
||||
6 files changed, 26 insertions(+)
|
||||
|
||||
diff --git a/src/AbstractProxyRequestCommand.cc b/src/AbstractProxyRequestCommand.cc
|
||||
index bd2bcb3..1feed07 100644
|
||||
--- a/src/AbstractProxyRequestCommand.cc
|
||||
+++ b/src/AbstractProxyRequestCommand.cc
|
||||
@@ -72,6 +72,7 @@ bool AbstractProxyRequestCommand::executeInternal()
|
||||
if (httpConnection_->sendBufferIsEmpty()) {
|
||||
auto httpRequest = make_unique<HttpRequest>();
|
||||
httpRequest->setUserAgent(getOption()->get(PREF_USER_AGENT));
|
||||
+ httpRequest->setNoWantDigest(!getOption()->getAsBool(PREF_HTTP_WANT_DIGEST));
|
||||
httpRequest->setRequest(getRequest());
|
||||
httpRequest->setProxyRequest(proxyRequest_);
|
||||
|
||||
diff --git a/src/HttpRequestCommand.cc b/src/HttpRequestCommand.cc
|
||||
index a2b8e7e..8c50153 100644
|
||||
--- a/src/HttpRequestCommand.cc
|
||||
+++ b/src/HttpRequestCommand.cc
|
||||
@@ -90,6 +90,7 @@ createHttpRequest(const std::shared_ptr<Request>& req,
|
||||
{
|
||||
auto httpRequest = make_unique<HttpRequest>();
|
||||
httpRequest->setUserAgent(option->get(PREF_USER_AGENT));
|
||||
+ httpRequest->setNoWantDigest(!option->getAsBool(PREF_HTTP_WANT_DIGEST));
|
||||
httpRequest->setRequest(req);
|
||||
httpRequest->setFileEntry(fileEntry);
|
||||
httpRequest->setSegment(segment);
|
||||
diff --git a/src/OptionHandlerFactory.cc b/src/OptionHandlerFactory.cc
|
||||
index a058eb9..9ff615a 100644
|
||||
--- a/src/OptionHandlerFactory.cc
|
||||
+++ b/src/OptionHandlerFactory.cc
|
||||
@@ -1106,6 +1106,18 @@ std::vector<OptionHandler*> OptionHandlerFactory::createOptionHandlers()
|
||||
op->setChangeOptionForReserved(true);
|
||||
handlers.push_back(op);
|
||||
}
|
||||
+ {
|
||||
+ OptionHandler* op(
|
||||
+ new BooleanOptionHandler(PREF_HTTP_WANT_DIGEST,
|
||||
+ TEXT_HTTP_WANT_DIGEST,
|
||||
+ A2_V_FALSE, OptionHandler::OPT_ARG));
|
||||
+ op->addTag(TAG_ADVANCED);
|
||||
+ op->addTag(TAG_HTTP);
|
||||
+ op->setInitialOption(true);
|
||||
+ op->setChangeGlobalOption(true);
|
||||
+ op->setChangeOptionForReserved(true);
|
||||
+ handlers.push_back(op);
|
||||
+ }
|
||||
{
|
||||
OptionHandler* op(new BooleanOptionHandler(
|
||||
PREF_ENABLE_HTTP_KEEP_ALIVE, TEXT_ENABLE_HTTP_KEEP_ALIVE, A2_V_TRUE,
|
||||
diff --git a/src/prefs.cc b/src/prefs.cc
|
||||
index 9793706..bdb33e2 100644
|
||||
--- a/src/prefs.cc
|
||||
+++ b/src/prefs.cc
|
||||
@@ -437,6 +437,8 @@ PrefPtr PREF_HTTP_ACCEPT_GZIP = makePref("http-accept-gzip");
|
||||
// value: true | false
|
||||
PrefPtr PREF_CONTENT_DISPOSITION_DEFAULT_UTF8 =
|
||||
makePref("content-disposition-default-utf8");
|
||||
+// values: true | false
|
||||
+PrefPtr PREF_HTTP_WANT_DIGEST = makePref("http-want-digest");
|
||||
|
||||
/**
|
||||
* Proxy related preferences
|
||||
diff --git a/src/prefs.h b/src/prefs.h
|
||||
index f014d9c..c88f2d0 100644
|
||||
--- a/src/prefs.h
|
||||
+++ b/src/prefs.h
|
||||
@@ -389,6 +389,8 @@ extern PrefPtr PREF_HTTP_NO_CACHE;
|
||||
extern PrefPtr PREF_HTTP_ACCEPT_GZIP;
|
||||
// value: true | false
|
||||
extern PrefPtr PREF_CONTENT_DISPOSITION_DEFAULT_UTF8;
|
||||
+// value: true | false
|
||||
+extern PrefPtr PREF_HTTP_WANT_DIGEST;
|
||||
|
||||
/**;
|
||||
* Proxy related preferences
|
||||
diff --git a/src/usage_text.h b/src/usage_text.h
|
||||
index 7a0a981..aee3ac0 100644
|
||||
--- a/src/usage_text.h
|
||||
+++ b/src/usage_text.h
|
||||
@@ -560,6 +560,14 @@
|
||||
" Content-Disposition header as UTF-8 instead of\n" \
|
||||
" ISO-8859-1, for example, the filename parameter,\n" \
|
||||
" but not the extended version filename*.")
|
||||
+#define TEXT_HTTP_WANT_DIGEST \
|
||||
+ _(" --http-want-digest[=true|false] Send Want-Digest HTTP requser header\n" \
|
||||
+ " with only limited hash algorithms:\n" \
|
||||
+ " SHA-512, SHA-256, and SHA-1.\n" \
|
||||
+ " The Want-Digest HTTP header is primarily used\n" \
|
||||
+ " in a HTTP request, to ask the responder to\n" \
|
||||
+ " provide a digest of the requested resource\n" \
|
||||
+ " using the Digest response header")
|
||||
#define TEXT_EVENT_POLL \
|
||||
_(" --event-poll=POLL Specify the method for polling events.")
|
||||
#define TEXT_BT_EXTERNAL_IP \
|
||||
--
|
||||
2.29.2
|
||||
|
71
autocore/Makefile
Normal file
71
autocore/Makefile
Normal file
@ -0,0 +1,71 @@
|
||||
#
|
||||
# Copyright (C) 2010-2011 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=autocore
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=29
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/autocore-arm
|
||||
TITLE:=ARM auto core script.
|
||||
MAINTAINER:=CN_SZTL
|
||||
DEPENDS:=@(arm||aarch64) \
|
||||
+TARGET_bcm27xx:bcm27xx-userland \
|
||||
+TARGET_bcm53xx:nvram \
|
||||
+ethtool
|
||||
VARIANT:=arm
|
||||
endef
|
||||
|
||||
define Package/autocore-x86
|
||||
TITLE:=x86/x64 auto core loadbalance script.
|
||||
MAINTAINER:=Lean / CN_SZTL
|
||||
DEPENDS:=@TARGET_x86 +bc +lm-sensors +ethtool
|
||||
VARIANT:=x86
|
||||
endef
|
||||
|
||||
define Package/autocore-arm/description
|
||||
Display more details info about the devices in LuCI.
|
||||
endef
|
||||
|
||||
define Download/armcpuinfo
|
||||
URL:=https://raw.githubusercontent.com/immortalwrt/immortalwrt/master/package/emortal/autocore/files/arm
|
||||
URL_FILE:=cpuinfo
|
||||
FILE:=cpuinfo
|
||||
HASH:=skip
|
||||
endef
|
||||
|
||||
define Build/Prepare
|
||||
sed -i 's/cpu_arch="?"/cpu_arch="ARMv8 Processor"/' $(DL_DIR)/cpuinfo
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/autocore-arm/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) $(DL_DIR)/cpuinfo $(1)/sbin/cpuinfo
|
||||
$(INSTALL_BIN) ./files/common/ethinfo $(1)/sbin/ethinfo
|
||||
$(INSTALL_DIR) $(1)/www/luci-static/resources/view/status/include
|
||||
$(INSTALL_DATA) ./files/common/29_eth.js $(1)/www/luci-static/resources/view/status/include/
|
||||
endef
|
||||
|
||||
define Package/autocore-x86/install
|
||||
$(INSTALL_DIR) $(1)/sbin
|
||||
$(INSTALL_BIN) ./files/x86/cpuinfo $(1)/sbin/cpuinfo
|
||||
$(INSTALL_BIN) ./files/common/ethinfo $(1)/sbin/ethinfo
|
||||
$(INSTALL_DIR) $(1)/www/luci-static/resources/view/status/include
|
||||
$(INSTALL_DATA) ./files/common/29_eth.js $(1)/www/luci-static/resources/view/status/include/
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/view/admin_status/index/
|
||||
$(INSTALL_DATA) ./files/x86/nvme_status.htm $(1)/usr/lib/lua/luci/view/admin_status/index/
|
||||
endef
|
||||
|
||||
$(eval $(call Download,armcpuinfo))
|
||||
$(eval $(call BuildPackage,autocore-arm))
|
||||
$(eval $(call BuildPackage,autocore-x86))
|
34
autocore/files/common/29_eth.js
Normal file
34
autocore/files/common/29_eth.js
Normal file
@ -0,0 +1,34 @@
|
||||
'use strict';
|
||||
'require rpc';
|
||||
|
||||
var callEthInfo = rpc.declare({
|
||||
object: 'luci',
|
||||
method: 'getEthInfo'
|
||||
});
|
||||
|
||||
return L.Class.extend({
|
||||
title: _('Interfaces'),
|
||||
|
||||
load: function() {
|
||||
return L.resolveDefault(callEthInfo(), {});
|
||||
},
|
||||
|
||||
render: function(info) {
|
||||
if (info && info.result) {
|
||||
var result = "";
|
||||
var ports = eval('(' + info.result + ')');
|
||||
var tmp = "<div class='table' width='100%' cellspacing='10' style='text-align: center' id='ethinfo'><ul style='list-style: none; margin:0 auto; display: inline-block;'>";
|
||||
for (var i in ports) {
|
||||
tmp = tmp + String.format(
|
||||
'<li style="float: left; margin: 0px 1em;"><span style="line-height:25px">%s</span><br /><small><img draggable="false" src="/luci-static/resources/icons/%s" /><br />%s<br />%s</small></li>',
|
||||
ports[i].name,
|
||||
ports[i].status ? 'port_up.png' : 'port_down.png',
|
||||
ports[i].speed,
|
||||
ports[i].duplex ? _('full-duplex') : _('half-duplex'));
|
||||
}
|
||||
tmp + "</ul></div>";
|
||||
result = tmp;
|
||||
return result;
|
||||
}
|
||||
}
|
||||
});
|
39
autocore/files/common/ethinfo
Normal file
39
autocore/files/common/ethinfo
Normal file
@ -0,0 +1,39 @@
|
||||
#!/bin/sh
|
||||
|
||||
a=$(ip address | grep ^[0-9] | awk -F: '{print $2}' | sed "s/ //g" | grep '^[e]' | grep -v "@" | grep -v "\.")
|
||||
b=$(echo "$a" | wc -l)
|
||||
rm -f /tmp/state/ethinfo
|
||||
|
||||
echo -n "[" > /tmp/state/ethinfo
|
||||
|
||||
for i in $(seq 1 $b)
|
||||
do
|
||||
h=$(echo '{"name":' )
|
||||
c=$(echo "$a" | sed -n ${i}p)
|
||||
d=$(ethtool $c)
|
||||
|
||||
e=$(echo "$d" | grep "Link detected" | awk -F: '{printf $2}' | sed 's/^[ \t]*//g')
|
||||
if [ $e = yes ]; then
|
||||
l=1
|
||||
else
|
||||
l=0
|
||||
fi
|
||||
|
||||
f=$(echo "$d" | grep "Speed" | awk -F: '{printf $2}' | sed 's/^[ \t]*//g' | tr -d "Unknown!")
|
||||
[ -z "$f" ] && f=" - "
|
||||
|
||||
g=$(echo "$d" | grep "Duplex" | awk -F: '{printf $2}' | sed 's/^[ \t]*//g')
|
||||
if [ "$g" == "Full" ]; then
|
||||
x=1
|
||||
else
|
||||
x=0
|
||||
fi
|
||||
|
||||
echo -n "$h \"$c\", \"status\": $l, \"speed\": \"$f\", \"duplex\": $x}," >> /tmp/state/ethinfo
|
||||
done
|
||||
|
||||
sed -i 's/.$//' /tmp/state/ethinfo
|
||||
|
||||
echo -n "]" >> /tmp/state/ethinfo
|
||||
|
||||
cat /tmp/state/ethinfo
|
5
autocore/files/x86/cpuinfo
Normal file
5
autocore/files/x86/cpuinfo
Normal file
@ -0,0 +1,5 @@
|
||||
#!/bin/sh
|
||||
|
||||
MHz=`grep 'MHz' /proc/cpuinfo | cut -c11- |sed -n '1p'`
|
||||
TEMP=`sensors 2>/dev/null | grep 'Core 0' | cut -c12-`
|
||||
echo "$MHz MHz $TEMP "
|
228
autocore/files/x86/nvme_status.htm
Normal file
228
autocore/files/x86/nvme_status.htm
Normal file
@ -0,0 +1,228 @@
|
||||
<% local raid = {}
|
||||
local devs = {}
|
||||
local devinfo = {}
|
||||
local colors = { "c0c0ff", "fbbd00", "e97c30", "a0e0a0", "b2c005", "e0c0ff" }
|
||||
local mounts = nixio.fs.readfile("/proc/mounts")
|
||||
|
||||
local show_raid = 1
|
||||
local show_disc = 1
|
||||
|
||||
if self then
|
||||
if self.hide_raid then
|
||||
show_raid = 0
|
||||
end
|
||||
if self.hide_disc then
|
||||
show_disc = 0
|
||||
end
|
||||
end
|
||||
|
||||
function disp_size(s)
|
||||
local units = { "kB", "MB", "GB", "TB" }
|
||||
local i, unit
|
||||
s = s / 2
|
||||
for i, unit in ipairs(units) do
|
||||
if (i == #units) or (s < 1024) then
|
||||
return math.floor(s * 100) / 100 .. unit
|
||||
end
|
||||
s = s / 1024
|
||||
end
|
||||
end
|
||||
|
||||
function first_line(s)
|
||||
local n = s:find("\n")
|
||||
if n then
|
||||
return s:sub(1, n-1)
|
||||
end
|
||||
return s
|
||||
end
|
||||
|
||||
function get_fs(pname, status)
|
||||
for r,raid in ipairs(raid) do
|
||||
for m,member in ipairs(raid.members) do
|
||||
if member.name == pname then
|
||||
return "(raid member)"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
local mounted_fs = mounts:match("\n[a-z/]*" .. pname .. " [^ ]* ([^ ]*)")
|
||||
if mounted_fs then
|
||||
if status == "standby" then
|
||||
return "(" .. mounted_fs .. ")"
|
||||
end
|
||||
local df = luci.sys.exec("df /dev/" .. pname):match(" ([0-9]+)%% ")
|
||||
return "(" .. mounted_fs .. " " .. df .. "%)"
|
||||
end
|
||||
|
||||
if status == "standby" then
|
||||
return
|
||||
end
|
||||
|
||||
local blkid = luci.sys.exec(" blkid -s TYPE /dev/" .. pname):match("TYPE=\"(.*)\"")
|
||||
if blkid then
|
||||
return "(" .. blkid .. ")"
|
||||
end
|
||||
end
|
||||
|
||||
function get_status(raid)
|
||||
for m,member in ipairs(raid.members) do
|
||||
for d,dev in ipairs(devinfo) do
|
||||
if member.name == dev.name then
|
||||
return dev.status
|
||||
end
|
||||
for p,part in ipairs(dev.parts) do
|
||||
if member.name == part.name then
|
||||
return dev.status
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function get_parts(dev,status,size)
|
||||
local c = 1
|
||||
local unused = size
|
||||
local parts = {}
|
||||
|
||||
for part in nixio.fs.glob("/sys/block/" .. dev .."/" .. dev .. "*") do
|
||||
local pname = nixio.fs.basename(part)
|
||||
local psize = nixio.fs.readfile(part .. "/size")
|
||||
table.insert(parts, {name=pname, size=psize, perc=math.floor(psize*100/size), fs=get_fs(pname,status), color=colors[c]})
|
||||
c = c + 1
|
||||
unused = unused - psize
|
||||
end
|
||||
if unused > 2048 then
|
||||
table.insert(parts, { name="", fs=get_fs(dev,status), size=unused, color=colors[c] })
|
||||
end
|
||||
return parts
|
||||
end
|
||||
|
||||
for dev in nixio.fs.glob("/sys/block/*") do
|
||||
if nixio.fs.access(dev .. "/md") then
|
||||
local name = nixio.fs.basename(dev)
|
||||
local rlevel = first_line(nixio.fs.readfile(dev .. "/md/level"))
|
||||
local ndisks = tonumber(nixio.fs.readfile(dev .. "/md/raid_disks"))
|
||||
local size = tonumber(nixio.fs.readfile(dev .. "/size"))
|
||||
local metav = nixio.fs.readfile(dev .. "/md/metadata_version")
|
||||
local degr = tonumber(nixio.fs.readfile(dev .. "/md/degraded"))
|
||||
local sync = first_line(nixio.fs.readfile(dev .. "/md/sync_action"))
|
||||
local sync_speed = tonumber(nixio.fs.readfile(dev .. "/md/sync_speed"))
|
||||
local sync_compl = nixio.fs.readfile(dev .. "/md/sync_completed")
|
||||
local status = "active"
|
||||
if sync ~= "idle" then
|
||||
local progress, total = nixio.fs.readfile(dev .. "/md/sync_completed"):match("^([0-9]*)[^0-9]*([0-9]*)")
|
||||
local rem = (total - progress) / sync_speed / 2
|
||||
local rems = math.floor(rem % 60)
|
||||
if rems < 10 then rems = "0" .. rems end
|
||||
rem = math.floor(rem / 60)
|
||||
local remm = math.floor(rem % 60)
|
||||
if remm < 10 then remm = "0" .. remm end
|
||||
local remh = math.floor(rem / 60)
|
||||
local remstr = remh .. ":" .. remm .. ":" .. rems
|
||||
status = sync .. " (" .. math.floor(sync_speed/1024) .. "MB/s, " .. math.floor(progress * 1000 / total) /10 .. "%, rem. " .. remstr .. ")"
|
||||
elseif degr == 1 then
|
||||
status = "degraded"
|
||||
end
|
||||
|
||||
local members = {}
|
||||
local c = 1
|
||||
for member in nixio.fs.glob("/sys/block/" .. name .. "/md/dev-*") do
|
||||
local dname = nixio.fs.basename(nixio.fs.readlink(member .. "/block"))
|
||||
local dsize = disp_size(tonumber(nixio.fs.readfile(member .. "/block/size")))
|
||||
local dstate = nixio.fs.readfile(member .. "/state"):gsub("_", " "):match "^%s*(.-)%s*$"
|
||||
table.insert(members, { name = dname, size = dsize, state = dstate, color = colors[c] })
|
||||
c = c + 1
|
||||
end
|
||||
table.insert(raid, {name=name, rlevel=rlevel, ndisks=ndisks, size=size, metav=metav, status=status, members=members })
|
||||
end
|
||||
end
|
||||
|
||||
if show_disc == 1 then
|
||||
for dev in nixio.fs.glob("/sys/class/nvme/*/device/nvme/*") do
|
||||
local section
|
||||
local model = nixio.fs.readfile(dev .. "/model")
|
||||
local fw = nixio.fs.readfile(dev .. "/firmware_rev")
|
||||
for bdev in nixio.fs.glob(dev .. "/nvme*") do
|
||||
local section
|
||||
local name = nixio.fs.basename(bdev)
|
||||
local size = tonumber(nixio.fs.readfile(bdev .. "/size"))
|
||||
local unused = size
|
||||
local status = "-"
|
||||
local temp = "-"
|
||||
local serial = "-"
|
||||
local secsize = "-"
|
||||
|
||||
for _,line in ipairs(luci.util.execl("smartctl -A -i -d nvme -n standby -f brief /dev/" .. name)) do
|
||||
local attrib, val
|
||||
if section == 1 then
|
||||
attrib, val = line:match "^(.*):%s*(.*)"
|
||||
elseif section == 2 then
|
||||
attrib, val = line:match("^([0-9 ]*) [^ ]* * [POSRCK-]* *[0-9-]* *[0-9-]* *[0-9-]* *[0-9-]* *([0-9-]*)")
|
||||
else
|
||||
attrib = line:match "^=== START OF (.*) SECTION ==="
|
||||
if attrib == "INFORMATION" then
|
||||
section = 1
|
||||
elseif attrib == "READ SMART DATA" then
|
||||
section = 2
|
||||
elseif status == "-" then
|
||||
val = line:match "^Device is in (.*) mode"
|
||||
if val then
|
||||
status = val:lower()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if not attrib then
|
||||
if section ~= 2 then section = 0 end
|
||||
elseif (attrib == "Power mode is") or (attrib == "Power mode was") then
|
||||
status = val:lower():match "(%S*)"
|
||||
elseif attrib == "Serial Number" then
|
||||
serial = val
|
||||
elseif attrib == "194" then
|
||||
temp = val .. "°C"
|
||||
end
|
||||
end
|
||||
table.insert(devinfo, {name=name, model=model, fw=fw, size=size, serial=serial, parts=get_parts(name,status,size) })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if show_raid == 1 and #devinfo > 0 then %>
|
||||
<div class="cbi-section">
|
||||
<h3><%:NVMe SSD%></h3>
|
||||
<table class="cbi-section-table" style="white-space: nowrap">
|
||||
<tr>
|
||||
<th width="5%"> </th>
|
||||
<th width="30%"><%:Model%></th>
|
||||
<th width="25%"><%:Serial number%></th>
|
||||
<th width="20%"><%:Firmware%></th>
|
||||
<th width="20%"><%:Capacity%></th>
|
||||
<!-- <th width="10%"><%:Temperature%></th>-->
|
||||
</tr>
|
||||
<% local style=true
|
||||
for d,dev in ipairs(devinfo) do %>
|
||||
<tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
|
||||
<td class="cbi-vluae-field" style="padding-bottom:0px; border-bottom-width:0px; vertical-align:middle" rowspan="4"><%=dev.name%></td>
|
||||
<td class="cbi-value-field" style="padding-bottom:0px; border-bottom-width:0px" rowspan="2"><%=dev.model%></td>
|
||||
<td class="cbi-value-field" style="padding-bottom:0px; border-bottom-width:0px" rowspan="2"><%=dev.serial%></td>
|
||||
<td class="cbi-value-field" style="padding-bottom:0px; border-bottom-width:0px" rowspan="2"><%=dev.fw%></td>
|
||||
<td class="cbi-value-field" style="padding-bottom:0px; border-bottom-width:0px" rowspan="2"><%=disp_size(dev.size)%></td>
|
||||
<!-- <td class="cbi-value-field" style="padding-bottom:0px; border-bottom-width:0px" rowspan="2"><%=dev.temp%></td>-->
|
||||
</tr>
|
||||
<tr style="height:0px" />
|
||||
<tr class="cbi-section-table-row cbi-rowstyle-<%=(style and 1 or 2)%>">
|
||||
<td style="padding:0px; border-top-width:0px" colspan="7" rowspan="2">
|
||||
<table style="border: 0pt; border-collapse:collapse; width:100%; padding:0px; margin:0px"><tr>
|
||||
<% for _,part in pairs(dev.parts) do %>
|
||||
<td style="text-align:center; padding: 0px 4px; border-radius: 3px; background-color:#<%=part.color%>" width="<%=part.perc%>%"><%=part.name%> <%=disp_size(part.size)%> <%=part.fs%></td>
|
||||
<% end %>
|
||||
</tr></table>
|
||||
</td>
|
||||
</tr>
|
||||
<tr style="height:0px" />
|
||||
<% style = not style
|
||||
end %>
|
||||
</table>
|
||||
</div>
|
||||
<% end %>
|
35
autoshare-ksmbd/Makefile
Normal file
35
autoshare-ksmbd/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright (C) 2010-2011 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=autoshare-ksmbd
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=11
|
||||
PKG_ARCH:=all
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/autoshare-ksmbd
|
||||
TITLE:=Samba autoconfig hotplug script.
|
||||
MAINTAINER:=Lean
|
||||
DEPENDS:=+wsdd2
|
||||
endef
|
||||
|
||||
define Package/autoshare-ksmbd/description
|
||||
A hotplug script to config Samba share automatically.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/autoshare-ksmbd/install
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/block
|
||||
$(INSTALL_BIN) ./files/20-smb-ksmbd $(1)/etc/hotplug.d/block/20-smb-ksmbd
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,autoshare-ksmbd))
|
113
autoshare-ksmbd/files/20-smb-ksmbd
Normal file
113
autoshare-ksmbd/files/20-smb-ksmbd
Normal file
@ -0,0 +1,113 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# D-Team Technology Co.,Ltd. ShenZhen
|
||||
# 作者:Vic
|
||||
#
|
||||
# 警告:对着屏幕的哥们,我们允许你使用此脚本,但不允许你抹去作者的信息,请保留这段话。
|
||||
#
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/service.sh
|
||||
|
||||
global=0
|
||||
config_file="/etc/config/ksmbd"
|
||||
|
||||
[ ! -f /etc/config/ksmbd ] && {
|
||||
echo "
|
||||
config globals
|
||||
option 'workgroup' 'WORKGROUP'
|
||||
option 'description' 'Ksmbd on OpenWrt'
|
||||
" > $config_file
|
||||
}
|
||||
|
||||
wait_for_init() {
|
||||
for i in `seq 30`
|
||||
do
|
||||
[ -e /tmp/procd.done ] || {
|
||||
sleep 1; continue;
|
||||
}
|
||||
return
|
||||
done
|
||||
}
|
||||
|
||||
smb_handle() {
|
||||
config_get path $1 path
|
||||
if [ "$path" = "$2" ] ;then
|
||||
global=1
|
||||
fi
|
||||
}
|
||||
|
||||
chk_en() {
|
||||
config_get_bool autoshare $1 autoshare 1
|
||||
[ $autoshare -eq 0 ] && exit
|
||||
}
|
||||
|
||||
config_load ksmbd
|
||||
config_foreach chk_en ksmbd
|
||||
|
||||
device=`basename $DEVPATH`
|
||||
|
||||
case "$ACTION" in
|
||||
add)
|
||||
|
||||
case "$device" in
|
||||
sd*);;
|
||||
md*);;
|
||||
hd*);;
|
||||
*) return;;
|
||||
esac
|
||||
|
||||
path="/dev/$device"
|
||||
|
||||
wait_for_init
|
||||
|
||||
cat /proc/mounts | while read j
|
||||
do
|
||||
str=${j%% *}
|
||||
if [ "$str" == $path ];then
|
||||
strr=${j#* }
|
||||
target=${strr%% *}
|
||||
global=0
|
||||
config_foreach smb_handle share $target
|
||||
name=${target#*/mnt/}
|
||||
name=$(echo $name | sed -e "s/^\///")
|
||||
if [ $global -eq 0 ] ;then
|
||||
echo -e "\n\nconfig share" >> $config_file
|
||||
echo -e "\toption auto '1'" >> $config_file
|
||||
echo -e "\toption name '$name'" >> $config_file
|
||||
echo -e "\toption path '$target'" >> $config_file
|
||||
echo -e "\toption read_only 'no'" >> $config_file
|
||||
echo -e "\toption guest_ok 'yes'" >> $config_file
|
||||
echo -e "\toption create_mask '0666'" >> $config_file
|
||||
echo -e "\toption dir_mask '0777'" >> $config_file
|
||||
echo -e "\toption device '$device'" >> $config_file
|
||||
echo -e "\toption force_root '1'" >> $config_file
|
||||
/etc/init.d/ksmbd reload
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
;;
|
||||
|
||||
remove)
|
||||
i=0
|
||||
while true
|
||||
do
|
||||
dev=`uci get ksmbd.@share[$i].device`
|
||||
[ $? -ne 0 ] && break
|
||||
|
||||
[ "$dev" = "$device" ] && {
|
||||
auto=`uci get ksmbd.@share[$i].auto`
|
||||
[ $auto = "1" ] && {
|
||||
mount_dir=`uci get ksmbd.@share[$i].name`
|
||||
uci delete ksmbd.@share[$i]
|
||||
uci commit
|
||||
/etc/init.d/ksmbd reload
|
||||
return
|
||||
}
|
||||
}
|
||||
let i+=1
|
||||
done
|
||||
;;
|
||||
esac
|
35
autoshare-samba/Makefile
Normal file
35
autoshare-samba/Makefile
Normal file
@ -0,0 +1,35 @@
|
||||
#
|
||||
# Copyright (C) 2010-2011 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=autoshare-samba
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=11
|
||||
PKG_ARCH:=all
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/autoshare-samba
|
||||
TITLE:=Samba autoconfig hotplug script.
|
||||
MAINTAINER:=Lean
|
||||
DEPENDS:=+wsdd2
|
||||
endef
|
||||
|
||||
define Package/autoshare-samba/description
|
||||
A hotplug script to config Samba share automatically.
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/autoshare-samba/install
|
||||
$(INSTALL_DIR) $(1)/etc/hotplug.d/block
|
||||
$(INSTALL_BIN) ./files/20-smb $(1)/etc/hotplug.d/block/20-smb
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,autoshare-samba))
|
114
autoshare-samba/files/20-smb
Normal file
114
autoshare-samba/files/20-smb
Normal file
@ -0,0 +1,114 @@
|
||||
#!/bin/sh
|
||||
|
||||
#
|
||||
# D-Team Technology Co.,Ltd. ShenZhen
|
||||
# 作者:Vic
|
||||
#
|
||||
# 警告:对着屏幕的哥们,我们允许你使用此脚本,但不允许你抹去作者的信息,请保留这段话。
|
||||
#
|
||||
|
||||
. /lib/functions.sh
|
||||
. /lib/functions/service.sh
|
||||
|
||||
global=0
|
||||
config_file="/etc/config/samba4"
|
||||
|
||||
[ ! -f /etc/config/samba4 ] && {
|
||||
echo "
|
||||
config samba
|
||||
option workgroup 'WORKGROUP'
|
||||
option charset 'UTF-8'
|
||||
option description 'Samba on OpenWRT'
|
||||
" > $config_file
|
||||
}
|
||||
|
||||
wait_for_init() {
|
||||
for i in `seq 30`
|
||||
do
|
||||
[ -e /tmp/procd.done ] || {
|
||||
sleep 1; continue;
|
||||
}
|
||||
return
|
||||
done
|
||||
}
|
||||
|
||||
smb_handle() {
|
||||
config_get path $1 path
|
||||
if [ "$path" = "$2" ] ;then
|
||||
global=1
|
||||
fi
|
||||
}
|
||||
|
||||
chk_en() {
|
||||
config_get_bool autoshare $1 autoshare 1
|
||||
[ $autoshare -eq 0 ] && exit
|
||||
}
|
||||
|
||||
config_load samba4
|
||||
config_foreach chk_en samba4
|
||||
|
||||
device=`basename $DEVPATH`
|
||||
|
||||
case "$ACTION" in
|
||||
add)
|
||||
|
||||
case "$device" in
|
||||
sd*);;
|
||||
md*);;
|
||||
hd*);;
|
||||
*) return;;
|
||||
esac
|
||||
|
||||
path="/dev/$device"
|
||||
|
||||
wait_for_init
|
||||
|
||||
cat /proc/mounts | while read j
|
||||
do
|
||||
str=${j%% *}
|
||||
if [ "$str" == $path ];then
|
||||
strr=${j#* }
|
||||
target=${strr%% *}
|
||||
global=0
|
||||
config_foreach smb_handle sambashare $target
|
||||
name=${target#*/mnt/}
|
||||
name=$(echo $name | sed -e "s/^\///")
|
||||
if [ $global -eq 0 ] ;then
|
||||
echo -e "\n\nconfig sambashare" >> $config_file
|
||||
echo -e "\toption auto '1'" >> $config_file
|
||||
echo -e "\toption name '$name'" >> $config_file
|
||||
echo -e "\toption path '$target'" >> $config_file
|
||||
echo -e "\toption read_only 'no'" >> $config_file
|
||||
echo -e "\toption guest_ok 'yes'" >> $config_file
|
||||
echo -e "\toption create_mask '0666'" >> $config_file
|
||||
echo -e "\toption dir_mask '0777'" >> $config_file
|
||||
echo -e "\toption device '$device'" >> $config_file
|
||||
echo -e "\toption force_root '1'" >> $config_file
|
||||
/etc/init.d/samba4 reload
|
||||
return
|
||||
fi
|
||||
fi
|
||||
done
|
||||
;;
|
||||
|
||||
remove)
|
||||
i=0
|
||||
while true
|
||||
do
|
||||
dev=`uci get samba4.@sambashare[$i].device`
|
||||
[ $? -ne 0 ] && break
|
||||
|
||||
[ "$dev" = "$device" ] && {
|
||||
auto=`uci get samba4.@sambashare[$i].auto`
|
||||
[ $auto = "1" ] && {
|
||||
mount_dir=`uci get samba4.@sambashare[$i].name`
|
||||
uci delete samba4.@sambashare[$i]
|
||||
uci commit
|
||||
/etc/init.d/samba4 reload
|
||||
return
|
||||
}
|
||||
}
|
||||
let i+=1
|
||||
done
|
||||
;;
|
||||
esac
|
41
bpytop/Makefile
Normal file
41
bpytop/Makefile
Normal file
@ -0,0 +1,41 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=bpytop
|
||||
PKG_VERSION:=1.0.67
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PYPI_NAME:=bpytop
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=Apache-2.0
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
|
||||
include ../../lang/python/pypi.mk
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include ../../lang/python/python3-package.mk
|
||||
|
||||
define Package/bpytop
|
||||
SECTION:=admin
|
||||
CATEGORY:=Administration
|
||||
TITLE:=Python port of bashtop
|
||||
URL:=https://github.com/aristocratos/bpytop
|
||||
DEPENDS:=+python3-psutil +python3-setuptools
|
||||
endef
|
||||
|
||||
define Package/bpytop/description
|
||||
Resource monitor that shows usage and stats for
|
||||
processor, memory, disks, network and processes.
|
||||
endef
|
||||
|
||||
define Py3Package/bpytop/install
|
||||
$(INSTALL_DIR) $(1)/usr/share
|
||||
$(CP) $(PKG_BUILD_DIR)/themes $(1)/usr/share/bpytop
|
||||
endef
|
||||
|
||||
$(eval $(call Py3Package,bpytop))
|
||||
$(eval $(call BuildPackage,bpytop))
|
||||
$(eval $(call BuildPackage,bpytop-src))
|
79
cdnspeedtest/Makefile
Normal file
79
cdnspeedtest/Makefile
Normal file
@ -0,0 +1,79 @@
|
||||
#
|
||||
# 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:=CloudflareSpeedTest
|
||||
PKG_VERSION:=1.5.1
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/XIU2/CloudflareSpeedTest/tar.gz/v$(PKG_VERSION)?
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=GPL-3.0
|
||||
PKG_LICENSE_FILE:=LICENSE
|
||||
PKG_MAINTAINER:=CN_SZTL <cnsztl@immortalwrt.org>
|
||||
|
||||
PKG_CONFIG_DEPENDS:= \
|
||||
CONFIG_CDNSPEEDTEST_COMPRESS_GOPROXY \
|
||||
CONFIG_CDNSPEEDTEST_COMPRESS_UPX
|
||||
|
||||
PKG_BUILD_DEPENDS:=golang/host
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_USE_MIPS16:=0
|
||||
|
||||
GO_PKG:=CloudflareSpeedTest
|
||||
GO_PKG_LDFLAGS:=-s -w
|
||||
GO_PKG_LDFLAGS_X:=main.version=v$(PKG_VERSION)
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include ../../lang/golang/golang-package.mk
|
||||
|
||||
define Package/cdnspeedtest
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
TITLE:=Getting the fastest ips to your network of CDN
|
||||
URL:=https://github.com/XIU2/CloudflareSpeedTest
|
||||
DEPENDS:=$(GO_ARCH_DEPENDS)
|
||||
endef
|
||||
|
||||
define Package/cdnspeedtest/config
|
||||
config CDNSPEEDTEST_COMPRESS_GOPROXY
|
||||
bool "Compiling with GOPROXY proxy"
|
||||
default n
|
||||
|
||||
config CDNSPEEDTEST_COMPRESS_UPX
|
||||
bool "Compress executable files with UPX"
|
||||
default y
|
||||
endef
|
||||
|
||||
ifeq ($(CONFIG_CDNSPEEDTEST_COMPRESS_GOPROXY),y)
|
||||
export GO111MODULE=on
|
||||
export GOPROXY=https://goproxy.baidu.com
|
||||
endif
|
||||
|
||||
define Build/Compile
|
||||
$(call GoPackage/Build/Compile)
|
||||
ifeq ($(CONFIG_CDNSPEEDTEST_COMPRESS_UPX),y)
|
||||
$(STAGING_DIR_HOST)/bin/upx --lzma --best $(GO_PKG_BUILD_BIN_DIR)/CloudflareSpeedTest
|
||||
endif
|
||||
endef
|
||||
|
||||
define Package/cdnspeedtest/install
|
||||
$(call GoPackage/Package/Install/Bin,$(PKG_INSTALL_DIR))
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/CloudflareSpeedTest $(1)/usr/bin/cdnspeedtest
|
||||
|
||||
$(INSTALL_DIR) $(1)/usr/share/CloudflareSpeedTest
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/ip.txt $(1)/usr/share/CloudflareSpeedTest/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/ipall.txt $(1)/usr/share/CloudflareSpeedTest/
|
||||
$(INSTALL_DATA) $(PKG_BUILD_DIR)/ipv6.txt $(1)/usr/share/CloudflareSpeedTest/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,cdnspeedtest))
|
266
cups/Makefile
Normal file
266
cups/Makefile
Normal file
@ -0,0 +1,266 @@
|
||||
#
|
||||
# Copyright (C) 2006-2016 OpenWrt.org
|
||||
# Copyright (C) 2016 lede-project.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=cups
|
||||
PKG_VERSION:=2.3.0
|
||||
PKG_RELEASE:=2
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION)-source.tar.gz
|
||||
PKG_SOURCE_URL:=https://github.com/apple/cups/releases/download/v$(PKG_VERSION)
|
||||
PKG_MD5SUM:=skip
|
||||
|
||||
TARGET_LDFLAGS+=-Wl,-rpath-link=$(STAGING_DIR)/usr/lib
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/cups/Default
|
||||
URL:=http://www.cups.org/
|
||||
SUBMENU:=Printing
|
||||
endef
|
||||
|
||||
define Package/cups
|
||||
$(call Package/cups/Default)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libcups +libusb-1.0 +libstdcpp
|
||||
TITLE:=Common UNIX Printing System (daemon)
|
||||
endef
|
||||
|
||||
define Package/cups/description
|
||||
Common UNIX Printing System (daemon)
|
||||
endef
|
||||
|
||||
define Package/cups/conffiles
|
||||
/etc/cups/classes.conf
|
||||
/etc/cups/cupsd.conf
|
||||
/etc/cups/printers.conf
|
||||
endef
|
||||
|
||||
define Package/cups-bsd
|
||||
$(call Package/cups/Default)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libcups
|
||||
TITLE:=Common UNIX Printing System - BSD commands (old)
|
||||
endef
|
||||
|
||||
define Package/cups-bsd/description
|
||||
Common UNIX Printing System - BSD commands (old)
|
||||
endef
|
||||
|
||||
define Package/cups-client
|
||||
$(call Package/cups/Default)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libcups +libcupsimage
|
||||
TITLE:=Common UNIX Printing System - Client commands
|
||||
endef
|
||||
|
||||
define Package/cups-client/conffiles
|
||||
/etc/cups/client.conf
|
||||
endef
|
||||
|
||||
define Package/cups-client/description
|
||||
Common UNIX Printing System - Client commands
|
||||
endef
|
||||
|
||||
define Package/cups-filters
|
||||
$(call Package/cups/Default)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libcupsimage
|
||||
TITLE:=Common UNIX Printing System - Filter
|
||||
endef
|
||||
|
||||
define Package/cups-filters/description
|
||||
Common UNIX Printing System - Filter
|
||||
endef
|
||||
|
||||
define Package/cups-ppdc
|
||||
$(call Package/cups/Default)
|
||||
SECTION:=net
|
||||
CATEGORY:=Network
|
||||
DEPENDS:=+libcups +zlib +libpthread +libpng +libjpeg +libstdcpp
|
||||
TITLE:=Common UNIX Printing System - PPDC utils
|
||||
endef
|
||||
|
||||
define Package/cups-ppdc/description
|
||||
Common UNIX Printing System - PPDC utils
|
||||
endef
|
||||
|
||||
define Package/libcups
|
||||
$(call Package/cups/Default)
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
DEPENDS:=+zlib +libpthread +libpng +libjpeg
|
||||
TITLE:=Common UNIX Printing System - Core library
|
||||
endef
|
||||
|
||||
define Package/libcups/description
|
||||
Common UNIX Printing System - Core library
|
||||
endef
|
||||
|
||||
define Package/libcupsimage
|
||||
$(call Package/cups/Default)
|
||||
SECTION:=libs
|
||||
CATEGORY:=Libraries
|
||||
DEPENDS:=+libcups
|
||||
TITLE:=Common UNIX Printing System - Image library
|
||||
endef
|
||||
|
||||
define Package/libcupsimage/description
|
||||
Common UNIX Printing System - Image library
|
||||
endef
|
||||
|
||||
define Build/Configure
|
||||
$(call Build/Configure/Default, \
|
||||
--with-cups-user="nobody" \
|
||||
--with-cups-group="nogroup" \
|
||||
--with-system-groups="root" \
|
||||
--with-pdftops="none" \
|
||||
--without-perl \
|
||||
--without-python \
|
||||
--without-php \
|
||||
--enable-default-shared \
|
||||
--enable-shared \
|
||||
--enable-image \
|
||||
--enable-libusb \
|
||||
--disable-acl \
|
||||
--disable-dnssd \
|
||||
--disable-dbus \
|
||||
--disable-avahi \
|
||||
--disable-launchd \
|
||||
--disable-ldap \
|
||||
--disable-pam \
|
||||
--disable-slp \
|
||||
--disable-gnutls \
|
||||
--disable-openssl \
|
||||
--disable-cdsassl \
|
||||
--disable-ssl \
|
||||
--disable-gssapi \
|
||||
--disable-tiff, \
|
||||
UNAME="Linux" \
|
||||
LIBS="$(TARGET_LDFLAGS) -lz -lpng -ljpeg" \
|
||||
)
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
$(MAKE) -C $(PKG_BUILD_DIR) \
|
||||
$(TARGET_CONFIGURE_OPTS) \
|
||||
DSTROOT="$(PKG_INSTALL_DIR)" \
|
||||
STRIP="/bin/true" \
|
||||
all install
|
||||
endef
|
||||
|
||||
define Package/cups/install
|
||||
rm -rf $(1)/etc/cups
|
||||
$(INSTALL_DIR) $(1)/etc/cups
|
||||
$(CP) $(PKG_INSTALL_DIR)/etc/cups/* $(1)/etc/cups/
|
||||
rm -rf $(1)/etc/cups/certs
|
||||
ln -sf /tmp $(1)/etc/cups/certs
|
||||
rm -f $(1)/usr/bin/cups-config
|
||||
$(INSTALL_DIR) $(1)/usr/lib/cups
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/cups/backend $(1)/usr/lib/cups
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/cups/cgi-bin $(1)/usr/lib/cups
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/cups/daemon $(1)/usr/lib/cups
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/cups/driver $(1)/usr/lib/cups
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/cups/monitor $(1)/usr/lib/cups
|
||||
$(INSTALL_DIR) $(1)/usr/share/cups/templates
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/cups/templates/*.tmpl \
|
||||
$(1)/usr/share/cups/templates/
|
||||
$(INSTALL_DIR) $(1)/usr/share/cups/mime
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/cups/mime/* $(1)/usr/share/cups/mime/
|
||||
### Do install docs: cups web interface relies on them
|
||||
$(INSTALL_DIR) $(1)/usr/share/doc/cups
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/doc/cups/*.*html \
|
||||
$(1)/usr/share/doc/cups/
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/doc/cups/*.css \
|
||||
$(1)/usr/share/doc/cups/
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/doc/cups/*.txt \
|
||||
$(1)/usr/share/doc/cups/
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/doc/cups/images \
|
||||
$(1)/usr/share/doc/cups/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
# overwrite default config with our own
|
||||
$(CP) ./files/etc/cups/* $(1)/etc/cups/
|
||||
# install initscript with priority 60
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/cupsd.init $(1)/etc/init.d/cupsd
|
||||
$(INSTALL_BIN) \
|
||||
$(PKG_INSTALL_DIR)/usr/sbin/{cupsctl,cupsd} \
|
||||
$(1)/usr/sbin/
|
||||
# needed for cups to find usb printers per http://wiki.openwrt.org/doc/howto/cups.server
|
||||
chmod 700 $(1)/usr/lib/cups/backend/usb
|
||||
endef
|
||||
|
||||
define Package/cups-bsd/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/{lprm,lpq,lpr} $(1)/usr/bin/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/sbin/lpc $(1)/usr/sbin/
|
||||
endef
|
||||
|
||||
define Package/cups-client/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) \
|
||||
$(PKG_INSTALL_DIR)/usr/bin/{lp,cancel,cupstestppd} \
|
||||
$(PKG_INSTALL_DIR)/usr/bin/{ipptool,lpoptions,lpstat} \
|
||||
$(1)/usr/bin/
|
||||
$(INSTALL_DIR) $(1)/usr/sbin
|
||||
$(INSTALL_BIN) \
|
||||
$(PKG_INSTALL_DIR)/usr/sbin/{cupsaccept,cupsfilter} \
|
||||
$(PKG_INSTALL_DIR)/usr/sbin/{lpadmin,lpinfo,lpmove} \
|
||||
$(1)/usr/sbin/
|
||||
(cd $(1)/usr/sbin; ln -sf cupsaccept accept; ln -sf cupsaccept cupsenable; ln -sf cupsaccept cupsdisable; ln -sf cupsaccept reject; ln -sf cupsaccept cupsreject;)
|
||||
$(INSTALL_DIR) $(1)/usr/share/cups/ipptool
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/share/cups/ipptool/* \
|
||||
$(1)/usr/share/cups/ipptool
|
||||
endef
|
||||
|
||||
define Package/cups-filters/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib/cups/filter
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/cups/filter/{commandtops,gziptoany,pstops,rastertoepson,rastertohp,rastertolabel,rastertopwg} \
|
||||
$(1)/usr/lib/cups/filter
|
||||
(cd $(1)/usr/lib/cups/filter; ln -sf rastertolabel rastertodymo;)
|
||||
endef
|
||||
|
||||
define Package/cups-ppdc/install
|
||||
$(INSTALL_DIR) $(1)/usr/bin
|
||||
$(INSTALL_BIN) \
|
||||
$(PKG_INSTALL_DIR)/usr/bin/{ppdc,ppdhtml,ppdi,ppdmerge,ppdpo} \
|
||||
$(1)/usr/bin/
|
||||
endef
|
||||
|
||||
define Package/libcups/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcups.so* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
define Package/libcupsimage/install
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcupsimage.so* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(2)/bin
|
||||
$(INSTALL_BIN) $(PKG_INSTALL_DIR)/usr/bin/cups-config $(2)/bin/
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/include/cups $(1)/usr/include/
|
||||
$(INSTALL_DIR) $(1)/usr/lib
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/lib/libcups*.so* $(1)/usr/lib/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,cups))
|
||||
$(eval $(call BuildPackage,libcups))
|
||||
$(eval $(call BuildPackage,libcupsimage))
|
||||
$(eval $(call BuildPackage,cups-bsd))
|
||||
$(eval $(call BuildPackage,cups-client))
|
||||
$(eval $(call BuildPackage,cups-filters))
|
||||
$(eval $(call BuildPackage,cups-ppdc))
|
27
cups/files/cupsd.init
Normal file
27
cups/files/cupsd.init
Normal file
@ -0,0 +1,27 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2006-2011 OpenWrt.org
|
||||
|
||||
START=50
|
||||
|
||||
start() {
|
||||
enable=$(uci get cupsd.config.enabled 2>/dev/null)
|
||||
if [ $enable -eq 1 ]; then
|
||||
sed -i 's/Port [0-9]*/Port '"$(uci get cupsd.config.port)"'/g' /etc/cups/cupsd.conf
|
||||
mkdir -m 0755 -p /var/cache/cups
|
||||
mkdir -m 0755 -p /var/cups
|
||||
mkdir -m 0755 -p /var/spool/cups/tmp
|
||||
service_start /usr/sbin/cupsd
|
||||
fi
|
||||
}
|
||||
|
||||
stop() {
|
||||
service_stop /usr/sbin/cupsd
|
||||
kill $(pidof cupsd) >/dev/null 2>&1 || killall -9 cupsd >/dev/null 2>&1
|
||||
}
|
||||
|
||||
reload(){
|
||||
stop
|
||||
sleep 2
|
||||
start
|
||||
echo "cupsd Server has restarted."
|
||||
}
|
7
cups/files/etc/cups/classes.conf
Normal file
7
cups/files/etc/cups/classes.conf
Normal file
@ -0,0 +1,7 @@
|
||||
########################################################################
|
||||
# #
|
||||
# This is a sample class configuration file. This file is included #
|
||||
# from the main configuration file (cups.conf) and lists all of the #
|
||||
# printer classes known to the system. #
|
||||
# #
|
||||
########################################################################
|
9
cups/files/etc/cups/client.conf
Normal file
9
cups/files/etc/cups/client.conf
Normal file
@ -0,0 +1,9 @@
|
||||
########################################################################
|
||||
# #
|
||||
# This is the CUPS client configuration file. This file is used to #
|
||||
# define client-specific parameters, such as the default server or #
|
||||
# default encryption settings. #
|
||||
# #
|
||||
########################################################################
|
||||
|
||||
Encryption Never
|
58
cups/files/etc/cups/cupsd.conf
Normal file
58
cups/files/etc/cups/cupsd.conf
Normal file
@ -0,0 +1,58 @@
|
||||
########################################################################
|
||||
# #
|
||||
# This is the CUPS configuration file. If you are familiar with #
|
||||
# Apache or any of the other popular web servers, we've followed the #
|
||||
# same format. Any configuration variable used here has the same #
|
||||
# semantics as the corresponding variable in Apache. If we need #
|
||||
# different functionality then a different name is used to avoid #
|
||||
# confusion... #
|
||||
# #
|
||||
########################################################################
|
||||
|
||||
|
||||
AccessLog syslog
|
||||
ErrorLog syslog
|
||||
LogLevel info
|
||||
PageLog syslog
|
||||
PreserveJobHistory No
|
||||
PreserveJobFiles No
|
||||
AutoPurgeJobs Yes
|
||||
MaxJobs 25
|
||||
MaxPrinterHistory 10
|
||||
#Printcap /etc/printcap
|
||||
#PrintcapFormat BSD
|
||||
RequestRoot /var/cups
|
||||
#RemoteRoot remroot
|
||||
#User nobody
|
||||
#Group nogroup
|
||||
# root permissions required to make cups work with the usb backend
|
||||
User root
|
||||
Group root
|
||||
RIPCache auto
|
||||
TempDir /var/cups
|
||||
Port 631
|
||||
HostNameLookups On
|
||||
KeepAlive On
|
||||
# No: "BrowseOrder" "BrowseAllow" "BrowseRemoteProtocols"
|
||||
Browsing Yes
|
||||
BrowsingWebIF Yes
|
||||
BrowseLocalProtocols DNSSD
|
||||
DefaultShared Yes
|
||||
WebInterface Yes
|
||||
Listen /var/run/cups/cups.sock
|
||||
|
||||
ServerAlias *
|
||||
|
||||
<Location />
|
||||
Order Allow,Deny
|
||||
Allow From 127.0.0.1
|
||||
Allow From 192.168.0.0/16
|
||||
</Location>
|
||||
|
||||
<Location /admin>
|
||||
AuthType Basic
|
||||
AuthClass System
|
||||
Order Allow,Deny
|
||||
Allow From 127.0.0.1
|
||||
Allow From 192.168.0.0/16
|
||||
</Location>
|
23
cups/files/etc/cups/printers.conf
Normal file
23
cups/files/etc/cups/printers.conf
Normal file
@ -0,0 +1,23 @@
|
||||
<DefaultPrinter USB>
|
||||
Info USB Printer
|
||||
Location
|
||||
DeviceURI usb:/dev/usb/lp0
|
||||
State Idle
|
||||
Accepting Yes
|
||||
JobSheets none none
|
||||
QuotaPeriod 0
|
||||
PageLimit 0
|
||||
KLimit 0
|
||||
</Printer>
|
||||
|
||||
<Printer LP>
|
||||
Info Parallel Port Printer
|
||||
Location
|
||||
DeviceURI parallel:/dev/printers/0
|
||||
State Idle
|
||||
Accepting Yes
|
||||
JobSheets none none
|
||||
QuotaPeriod 0
|
||||
PageLimit 0
|
||||
KLimit 0
|
||||
</Printer>
|
33
cups/patches/150-64bit_host_fix.patch
Normal file
33
cups/patches/150-64bit_host_fix.patch
Normal file
@ -0,0 +1,33 @@
|
||||
--- a/config-scripts/cups-directories.m4
|
||||
+++ b/config-scripts/cups-directories.m4
|
||||
@@ -102,7 +102,7 @@ if test "$libdir" = "\${exec_prefix}/lib"; then
|
||||
case "$host_os_name" in
|
||||
linux*)
|
||||
if test -d /usr/lib64 -a ! -d /usr/lib64/fakeroot; then
|
||||
- libdir="$exec_prefix/lib64"
|
||||
+ libdir="$exec_prefix/lib"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
--- "a/configure"
|
||||
+++ "b/configure"
|
||||
@@ -6188,7 +6188,7 @@ if test "$libdir" = "\${exec_prefix}/lib"; then
|
||||
case "$host_os_name" in
|
||||
linux*)
|
||||
if test -d /usr/lib64 -a ! -d /usr/lib64/fakeroot; then
|
||||
- libdir="$exec_prefix/lib64"
|
||||
+ libdir="$exec_prefix/lib"
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
--- a/cups-config.in
|
||||
+++ b/cups-config.in
|
||||
@@ -48,7 +48,7 @@ else
|
||||
CFLAGS="$CFLAGS -I$includedir"
|
||||
fi
|
||||
|
||||
- if test $libdir != /usr/lib -a $libdir != /usr/lib32 -a $libdir != /usr/lib64; then
|
||||
+ if test $libdir != /usr/lib -a $libdir != /usr/lib -a $libdir != /usr/lib; then
|
||||
LDFLAGS="$LDFLAGS -L$libdir"
|
||||
fi
|
||||
fi
|
@ -1,42 +0,0 @@
|
||||
# 项目迁移了,请看:
|
||||
|
||||
项目已经迁移到新地址:https://github.com/linkease/nas-packages
|
||||
|
||||
# ddnsto-openwrt
|
||||
ddnsto for openwrt
|
||||
|
||||
## 使用方法
|
||||
|
||||
把文件夹 ddnsto 拷贝到 Openwrt 源代码的 package/network/services 里面,拷贝之后为:
|
||||
|
||||
```
|
||||
tree package/network/services/ddnsto
|
||||
package/network/services/ddnsto
|
||||
├── files
|
||||
│ ├── ddnsto.config
|
||||
│ ├── ddnsto.init
|
||||
│ └── ddnsto.uci-default
|
||||
└── Makefile
|
||||
```
|
||||
|
||||
### make menuconfig 选择方法
|
||||
|
||||
```
|
||||
make menuconfig
|
||||
|
||||
Network --->
|
||||
Web Servers/Proxies --->
|
||||
<*> ddnsto....................................... DDNS.to - the reverse proxy
|
||||
|
||||
LuCI --->
|
||||
3. Applications --->
|
||||
<*> luci-app-ddnsto.................................. LuCI support for ddnsto
|
||||
```
|
||||
|
||||
### 部分 Openwrt 老版本兼容性问题
|
||||
|
||||
安装完成点击配置,需要手动运行命令:
|
||||
|
||||
```
|
||||
/etc/init.d/ddnsto enable
|
||||
```
|
@ -14,7 +14,7 @@ PKG_VERSION:=0.3.0
|
||||
PKG_RELEASE:=1
|
||||
PKG_SOURCE:=$(PKG_NAME)-binary-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://firmware.koolshare.cn/binary/ddnsto/
|
||||
PKG_HASH:=cefd2494cb1c21e2c1616290f715dd6415cd460aafc107c38bb9910c13f42448
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_BUILD_DIR:=$(BUILD_DIR)/$(PKG_NAME)-binary-$(PKG_VERSION)
|
||||
|
51
default-settings/Makefile
Normal file
51
default-settings/Makefile
Normal file
@ -0,0 +1,51 @@
|
||||
#
|
||||
# Copyright (C) 2010-2011 OpenWrt.org
|
||||
#
|
||||
# This is free software, licensed under the GNU General Public License v2.
|
||||
# See /LICENSE for more information.
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=default-settings
|
||||
PKG_VERSION:=1
|
||||
PKG_RELEASE:=10
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/default-settings
|
||||
SECTION:=luci
|
||||
CATEGORY:=LuCI
|
||||
TITLE:=Default Settings
|
||||
MAINTAINER:=Kiddin'
|
||||
PKGARCH:=all
|
||||
DEPENDS:=+luci-base
|
||||
endef
|
||||
|
||||
define Package/default-settings/conffiles
|
||||
/etc/config/base_config
|
||||
endef
|
||||
|
||||
define Build/Compile
|
||||
endef
|
||||
|
||||
define Package/default-settings/install
|
||||
$(INSTALL_DIR) $(1)/etc/uci-defaults
|
||||
$(INSTALL_DATA) ./files/uci.defaults $(1)/etc/uci-defaults/95-default-settings
|
||||
$(INSTALL_DIR) $(1)/etc/config
|
||||
$(INSTALL_DATA) ./files/base_config.conf $(1)/etc/config/base_config
|
||||
$(INSTALL_DIR) $(1)/lib/wifi
|
||||
$(INSTALL_DATA) ./files/wifi-init.sh $(1)/lib/wifi/wifi-init.sh
|
||||
$(INSTALL_DIR) $(1)/etc/init.d
|
||||
$(INSTALL_BIN) ./files/wifi-init.init $(1)/etc/init.d/wifi-init
|
||||
$(INSTALL_DIR) $(1)/etc/rc.d
|
||||
$(INSTALL_BIN) ./files/opkg.rc.d $(1)/etc/rc.d/S99opkg
|
||||
$(INSTALL_DIR) $(1)/etc/profile.d
|
||||
$(INSTALL_BIN) ./files/sysinfo.sh $(1)/etc/profile.d/sysinfo.sh
|
||||
$(INSTALL_DIR) $(1)/usr/lib/lua/luci/i18n
|
||||
po2lmo ./po/zh_Hans/default.po $(1)/usr/lib/lua/luci/i18n/default.zh-cn.lmo
|
||||
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,default-settings))
|
||||
|
3
default-settings/files/base_config.conf
Normal file
3
default-settings/files/base_config.conf
Normal file
@ -0,0 +1,3 @@
|
||||
config status
|
||||
option version '0'
|
||||
option base '1'
|
93
default-settings/files/opkg.rc.d
Normal file
93
default-settings/files/opkg.rc.d
Normal file
@ -0,0 +1,93 @@
|
||||
#!/bin/sh
|
||||
LOCK=/var/lock/opkgupgrade.lock
|
||||
BKOPKG="/etc/backup"
|
||||
# 防止重复启动
|
||||
[ -f $LOCK ] && exit 1
|
||||
touch $LOCK
|
||||
mkdir -p $BKOPKG
|
||||
if [ ! -f /etc/inited ]; then
|
||||
[ "$(uci -q get dhcp.@dnsmasq[0].noresolv)" ] && {
|
||||
uci -q del dhcp.@dnsmasq[0].noresolv
|
||||
uci commit dhcp
|
||||
service dnsmasq reload
|
||||
}
|
||||
# sh -c "cat '/usr/share/patch/adblock.patch' | patch -d '/' -p1 --forward" >/dev/null 2>&1
|
||||
fi
|
||||
|
||||
if [ ! -f "$BKOPKG/user_installed.opkg" ]; then
|
||||
touch /etc/inited
|
||||
fi
|
||||
|
||||
function opkgupgrade() {
|
||||
c1=0
|
||||
c2=0
|
||||
c3=0
|
||||
while ! curl --retry 3 -m 5 https://op.supes.top >/dev/null 2>&1;do
|
||||
echo "无法连接仓库服务器,请检查网络. $c1" | sed -e "s/^/$(date +%Y-%m-%d" "%H:%M:%S) /" >>/tmp/opkgupdate.log
|
||||
[ $c1 == 120 ] && return || let c1++
|
||||
sleep 5
|
||||
done
|
||||
while :; do
|
||||
opkg update | sed -e "s/^/$(date +%Y-%m-%d" "%H:%M:%S) /" >>/tmp/opkgupdate.log 2>&1
|
||||
if [ "$?" == "0" ]; then
|
||||
def="$(opkg list-upgradable | cut -f 1 -d ' ' | grep -vE 'opkg|luci-lib-fs|firewall|base-files|luci-base|busybox|dnsmasq-full|coremark|miniupnpd|luci-mod-network|luci-mod-status|luci-mod-system')"
|
||||
if [ ! -f /etc/inited ]; then
|
||||
insed="$(cat $BKOPKG/user_installed.opkg)"
|
||||
fi
|
||||
upopkg="$insed $def"
|
||||
if [ "$upopkg" != " " ]; then
|
||||
for ipk in $upopkg; do
|
||||
while :; do
|
||||
opkg install --force-overwrite --force-checksum --force-depends $ipk | sed -e "s/^/$(date +%Y-%m-%d" "%H:%M:%S) /" >>/tmp/opkgupdate.log 2>&1 || true
|
||||
if [[ $ipk == luci-app-* ]]; then
|
||||
opkg install --force-overwrite --force-checksum luci-i18n-"$(echo $ipk | cut -d - -f 3-4)"-zh-cn | sed -e "s/^/$(date +%Y-%m-%d" "%H:%M:%S) /" >>/tmp/opkgupdate.log 2>&1 || true
|
||||
fi
|
||||
[[ "$(opkg list-installed | grep $ipk)" ]] && {
|
||||
break
|
||||
}
|
||||
[ $c2 == 3 ] && {
|
||||
echo $ipk >> $BKOPKG/failed.txt
|
||||
sed -i '/$ipk/d' $BKOPKG/user_installed.opkg
|
||||
break
|
||||
} || let c2++
|
||||
sleep 1
|
||||
rm -f /var/lock/opkg.lock
|
||||
done
|
||||
done
|
||||
rm -f /etc/config/*-opkg
|
||||
fi
|
||||
[[ -f $BKOPKG/failed.txt && -f /etc/inited ]] && {
|
||||
for ipk in $(cat $BKOPKG/failed.txt); do
|
||||
opkg install --force-overwrite --force-checksum --force-depends $ipk | sed -e "s/^/$(date +%Y-%m-%d" "%H:%M:%S) /" >>/tmp/opkgupdate.log 2>&1 || true
|
||||
[[ "$(opkg list-installed | grep $ipk)" ]] && {
|
||||
sed -i '/$ipk/d' $BKOPKG/failed.txt
|
||||
}
|
||||
done
|
||||
mv $BKOPKG/failed.txt $BKOPKG/failed_.txt
|
||||
}
|
||||
touch /etc/inited
|
||||
rm -f /var/lock/opkg.lock
|
||||
break
|
||||
fi
|
||||
[ $c3 == 10 ] && break || let c3++
|
||||
done
|
||||
rm -f /var/lock/opkg.lock
|
||||
}
|
||||
(
|
||||
if [[ ! -f /etc/inited || -f $BKOPKG/failed.txt ]]; then
|
||||
opkgupgrade || true
|
||||
elif [[ -f /etc/inited && `uci -q get system.@system[0].autoupgrade_pkg || echo "1"` != '0' ]]; then
|
||||
opkgupgrade || true
|
||||
fi
|
||||
rm -f /var/lock/opkg.lock
|
||||
|
||||
[[ -f "/bin/coremark" && ! -f "/etc/bench.log" ]] && {
|
||||
sleep 5
|
||||
/bin/coremark >/tmp/coremark.log
|
||||
cat /tmp/coremark.log | grep "CoreMark 1.0" | cut -d "/" -f 1 >/etc/bench.log
|
||||
sed -i 's/CoreMark 1.0/(CpuMark/g' /etc/bench.log
|
||||
echo " Scores)" >>/etc/bench.log
|
||||
}
|
||||
|
||||
rm -f $LOCK
|
||||
) &
|
151
default-settings/files/sysinfo.sh
Normal file
151
default-settings/files/sysinfo.sh
Normal file
@ -0,0 +1,151 @@
|
||||
#!/bin/bash
|
||||
|
||||
export PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||
export LANG=zh_CN.UTF-8
|
||||
|
||||
THIS_SCRIPT="sysinfo"
|
||||
MOTD_DISABLE=""
|
||||
|
||||
SHOW_IP_PATTERN="^[ewr].*|^br.*|^lt.*|^umts.*"
|
||||
|
||||
DATA_STORAGE=/userdisk/data
|
||||
MEDIA_STORAGE=/userdisk/snail
|
||||
|
||||
|
||||
[[ -f /etc/default/motd ]] && . /etc/default/motd
|
||||
for f in $MOTD_DISABLE; do
|
||||
[[ $f == $THIS_SCRIPT ]] && exit 0
|
||||
done
|
||||
|
||||
|
||||
# don't edit below here
|
||||
function display()
|
||||
{
|
||||
# $1=name $2=value $3=red_limit $4=minimal_show_limit $5=unit $6=after $7=acs/desc{
|
||||
# battery red color is opposite, lower number
|
||||
if [[ "$1" == "Battery" ]]; then
|
||||
local great="<";
|
||||
else
|
||||
local great=">";
|
||||
fi
|
||||
if [[ -n "$2" && "$2" > "0" && (( "${2%.*}" -ge "$4" )) ]]; then
|
||||
printf "%-14s%s" "$1:"
|
||||
if awk "BEGIN{exit ! ($2 $great $3)}"; then
|
||||
echo -ne "\e[0;91m $2";
|
||||
else
|
||||
echo -ne "\e[0;92m $2";
|
||||
fi
|
||||
printf "%-1s%s\x1B[0m" "$5"
|
||||
printf "%-11s%s\t" "$6"
|
||||
return 1
|
||||
fi
|
||||
} # display
|
||||
|
||||
|
||||
function get_ip_addresses()
|
||||
{
|
||||
local ips=()
|
||||
for f in /sys/class/net/*; do
|
||||
local intf=$(basename $f)
|
||||
# match only interface names starting with e (Ethernet), br (bridge), w (wireless), r (some Ralink drivers use ra<number> format)
|
||||
if [[ $intf =~ $SHOW_IP_PATTERN ]]; then
|
||||
local tmp=$(ip -4 addr show dev $intf | awk '/inet/ {print $2}' | cut -d'/' -f1)
|
||||
# add both name and IP - can be informative but becomes ugly with long persistent/predictable device names
|
||||
#[[ -n $tmp ]] && ips+=("$intf: $tmp")
|
||||
# add IP only
|
||||
[[ -n $tmp ]] && ips+=("$tmp")
|
||||
fi
|
||||
done
|
||||
echo "${ips[@]}"
|
||||
} # get_ip_addresses
|
||||
|
||||
|
||||
function storage_info()
|
||||
{
|
||||
# storage info
|
||||
RootInfo=$(df -h /)
|
||||
root_usage=$(awk '/\// {print $(NF-1)}' <<<${RootInfo} | sed 's/%//g')
|
||||
root_total=$(awk '/\// {print $(NF-4)}' <<<${RootInfo})
|
||||
|
||||
# storage info
|
||||
[ -d /boot ] && {
|
||||
BootInfo=$(df -h /boot) 2>/dev/null
|
||||
boot_usage=$(awk '/\// {print $(NF-1)}' <<<${BootInfo} | sed 's/%//g')
|
||||
boot_total=$(awk '/\// {print $(NF-4)}' <<<${BootInfo})
|
||||
}
|
||||
StorageInfo=$(df -h $MEDIA_STORAGE 2>/dev/null | grep $MEDIA_STORAGE)
|
||||
if [[ -n "${StorageInfo}" && ${RootInfo} != *$MEDIA_STORAGE* ]]; then
|
||||
media_usage=$(awk '/\// {print $(NF-1)}' <<<${StorageInfo} | sed 's/%//g')
|
||||
media_total=$(awk '/\// {print $(NF-4)}' <<<${StorageInfo})
|
||||
fi
|
||||
|
||||
StorageInfo=$(df -h $DATA_STORAGE 2>/dev/null | grep $DATA_STORAGE)
|
||||
if [[ -n "${StorageInfo}" && ${RootInfo} != *$DATA_STORAGE* ]]; then
|
||||
data_usage=$(awk '/\// {print $(NF-1)}' <<<${StorageInfo} | sed 's/%//g')
|
||||
data_total=$(awk '/\// {print $(NF-4)}' <<<${StorageInfo})
|
||||
fi
|
||||
} # storage_info
|
||||
|
||||
|
||||
# query various systems and send some stuff to the background for overall faster execution.
|
||||
# Works only with ambienttemp and batteryinfo since A20 is slow enough :)
|
||||
ip_address=$(get_ip_addresses &)
|
||||
storage_info
|
||||
critical_load=$(( 1 + $(grep -c processor /proc/cpuinfo) / 2 ))
|
||||
|
||||
# get uptime, logged in users and load in one take
|
||||
UptimeString=$(uptime | tr -d ',')
|
||||
time=$(awk -F" " '{print $3" "$4}' <<<"${UptimeString}")
|
||||
load="$(awk -F"average: " '{print $2}'<<<"${UptimeString}")"
|
||||
case ${time} in
|
||||
1:*) # 1-2 hours
|
||||
time=$(awk -F" " '{print $3" 小时"}' <<<"${UptimeString}")
|
||||
;;
|
||||
*:*) # 2-24 hours
|
||||
time=$(awk -F" " '{print $3" 小时"}' <<<"${UptimeString}")
|
||||
;;
|
||||
*day) # days
|
||||
days=$(awk -F" " '{print $3"天"}' <<<"${UptimeString}")
|
||||
time=$(awk -F" " '{print $5}' <<<"${UptimeString}")
|
||||
time="$days "$(awk -F":" '{print $1"小时 "$2"分钟"}' <<<"${time}")
|
||||
;;
|
||||
esac
|
||||
|
||||
|
||||
# memory and swap
|
||||
mem_info=$(LC_ALL=C free -w 2>/dev/null | grep "^Mem" || LC_ALL=C free | grep "^Mem")
|
||||
memory_usage=$(awk '{printf("%.0f",(($2-($4+$6))/$2) * 100)}' <<<${mem_info})
|
||||
memory_total=$(awk '{printf("%d",$2/1024)}' <<<${mem_info})
|
||||
swap_info=$(LC_ALL=C free -m | grep "^Swap")
|
||||
swap_usage=$( (awk '/Swap/ { printf("%3.0f", $3/$2*100) }' <<<${swap_info} 2>/dev/null || echo 0) | tr -c -d '[:digit:]')
|
||||
swap_total=$(awk '{print $(2)}' <<<${swap_info})
|
||||
|
||||
|
||||
# display info
|
||||
display "系统负载" "${load%% *}" "${critical_load}" "0" "" "${load#* }"
|
||||
printf "运行时间: \x1B[92m%s\x1B[0m\t\t" "$time"
|
||||
echo "" # fixed newline
|
||||
|
||||
|
||||
display "内存已用" "$memory_usage" "70" "0" " %" " of ${memory_total}MB"
|
||||
display "交换内存" "$swap_usage" "10" "0" " %" " of $swap_total""Mb"
|
||||
printf "IP 地址: \x1B[92m%s\x1B[0m" "$ip_address"
|
||||
echo "" # fixed newline
|
||||
|
||||
|
||||
a=0;b=0;c=0
|
||||
display "CPU 温度" "$board_temp" "45" "0" "°C" "" ; a=$?
|
||||
display "环境温度" "$amb_temp" "40" "0" "°C" "" ; b=$?
|
||||
(( ($a+$b) >0 )) && echo "" # new line only if some value is displayed
|
||||
|
||||
|
||||
display "启动存储" "$boot_usage" "90" "1" "%" " of $boot_total"
|
||||
display "系统存储" "$root_usage" "90" "1" "%" " of $root_total"
|
||||
echo ""
|
||||
|
||||
display "数据存储" "$data_usage" "90" "1" "%" " of $data_total"
|
||||
display "媒体存储" "$media_usage" "90" "1" "%" " of $media_total"
|
||||
echo ""
|
||||
echo ""
|
||||
|
||||
|
0
default-settings/files/uci.defaults
Normal file
0
default-settings/files/uci.defaults
Normal file
34
default-settings/files/wifi-init.init
Normal file
34
default-settings/files/wifi-init.init
Normal file
@ -0,0 +1,34 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2020 X-WRT.COM
|
||||
|
||||
START=19
|
||||
|
||||
boot() {
|
||||
. /lib/wifi/wifi-init.sh
|
||||
|
||||
local base wifi_init
|
||||
local SSID SSID_PASSWD
|
||||
|
||||
base=`uci get base_config.@status[0].base 2>/dev/null`
|
||||
base=$((base+0))
|
||||
wifi_init=`uci get base_config.@status[0].wifi_init 2>/dev/null`
|
||||
wifi_init=$((wifi_init+0))
|
||||
|
||||
test $base -lt 1 && {
|
||||
wifi_init=1 #skip wifi_init=1 hook
|
||||
}
|
||||
|
||||
test $wifi_init -lt 1 && {
|
||||
wifi_first_init
|
||||
|
||||
wifi_init=1
|
||||
}
|
||||
|
||||
uci set base_config.@status[0].wifi_init=$wifi_init
|
||||
uci commit base_config
|
||||
|
||||
#XXX
|
||||
test -f /rom/etc/uci-defaults/96-wizard-defaults && sh /rom/etc/uci-defaults/96-wizard-defaults
|
||||
|
||||
/etc/init.d/wifi-init disable
|
||||
}
|
81
default-settings/files/wifi-init.sh
Normal file
81
default-settings/files/wifi-init.sh
Normal file
@ -0,0 +1,81 @@
|
||||
#!/bin/sh
|
||||
|
||||
wifi_setup_radio()
|
||||
{
|
||||
local radio=$1
|
||||
|
||||
uci get wireless.${radio} >/dev/null 2>&1 && {
|
||||
#FIXME hack
|
||||
local path
|
||||
if test -e /sys/kernel/debug/ieee80211/phy0/mt76/dbdc &&
|
||||
[ "$(readlink /sys/class/ieee80211/phy0/device)" = "$(readlink /sys/class/ieee80211/phy1/device)" ]; then
|
||||
path="$(uci get wireless.${radio}.path)"
|
||||
if test -z "${path#*+1}"; then
|
||||
uci set wireless.${radio}.phy='phy1'
|
||||
uci set wireless.${radio}.htmode='VHT80'
|
||||
uci set wireless.${radio}.hwmode='11a'
|
||||
else
|
||||
uci set wireless.${radio}.phy='phy0'
|
||||
uci set wireless.${radio}.htmode='HT20'
|
||||
uci set wireless.${radio}.hwmode='11g'
|
||||
fi
|
||||
uci delete wireless.${radio}.path
|
||||
fi
|
||||
|
||||
uci -q batch <<-EOT
|
||||
set wireless.${radio}.disabled='0'
|
||||
set wireless.${radio}.country='CN'
|
||||
set wireless.${radio}.channel='auto'
|
||||
EOT
|
||||
|
||||
if [ x`uci get wireless.${radio}.hwmode 2>/dev/null` = "x11a" ]; then
|
||||
uci set wireless.${radio}.txpower='23'
|
||||
else
|
||||
uci set wireless.${radio}.txpower='20'
|
||||
fi
|
||||
|
||||
obj=`uci add wireless wifi-iface`
|
||||
test -n "$obj" && {
|
||||
uci set wireless.$obj.device="${radio}"
|
||||
uci set wireless.$obj.network='lan'
|
||||
uci set wireless.$obj.mode='ap'
|
||||
if [ x`uci get wireless.${radio}.hwmode 2>/dev/null` = "x11a" ]; then
|
||||
uci set wireless.$obj.ssid="${SSID}_5G"
|
||||
else
|
||||
uci set wireless.$obj.ssid="${SSID}_2.4G"
|
||||
fi
|
||||
# uci set wireless.$obj.encryption='psk2'
|
||||
uci set wireless.$obj.skip_inactivity_poll='1'
|
||||
uci set wireless.$obj.wpa_group_rekey='0'
|
||||
uci set wireless.$obj.wpa_pair_rekey='0'
|
||||
uci set wireless.$obj.wpa_master_rekey='0'
|
||||
uci set wireless.$obj.disassoc_low_ack='0'
|
||||
# uci set wireless.$obj.key="${SSID_PASSWD}"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
wifi_first_init()
|
||||
{
|
||||
SSID="${SSID-$(uci get base_config.@status[0].SSID 2>/dev/null || echo OpenWrt)}"
|
||||
SSID_PASSWD="${SSID_PASSWD-$(uci get base_config.@status[0].SSID_PASSWD 2>/dev/null || echo 88888888)}"
|
||||
|
||||
while uci delete wireless.@wifi-iface[0] >/dev/null 2>&1; do :; done
|
||||
for radio in radio0 radio1 radio2 radio3 wifi0 wifi1 wifi2 wifi3; do
|
||||
wifi_setup_radio ${radio}
|
||||
done
|
||||
uci commit wireless
|
||||
|
||||
# wireless migration
|
||||
local widx=0
|
||||
local change=0
|
||||
while uci rename wireless.@wifi-iface[$widx]=wifinet$widx >/dev/null 2>&1; do widx=$((widx+1)); done
|
||||
uci changes wireless | tr ".='" " " | while read _ a b; do
|
||||
if [ "x$a" != "x$b" ]; then
|
||||
uci commit wireless
|
||||
change=1
|
||||
break
|
||||
fi
|
||||
done
|
||||
[ "x$change" = "x0" ] && uci revert wireless
|
||||
}
|
166
default-settings/po/zh_Hans/default.po
Normal file
166
default-settings/po/zh_Hans/default.po
Normal file
@ -0,0 +1,166 @@
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"PO-Revision-Date: 2021-04-12 14:21+0000\n"
|
||||
"Language: zh_Hans\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"Plural-Forms: nplurals=1; plural=0;\n"
|
||||
"X-Generator: Weblate 4.5-dev\n"
|
||||
|
||||
msgid "Processor"
|
||||
msgstr "处理器"
|
||||
|
||||
msgid "Architecture"
|
||||
msgstr "架构"
|
||||
|
||||
msgid "CPU Temperature"
|
||||
msgstr "CPU 温度"
|
||||
|
||||
msgid "CPU Info"
|
||||
msgstr "CPU 信息"
|
||||
|
||||
msgid "CPU Model"
|
||||
msgstr "处理器型号"
|
||||
|
||||
msgid "CPU frequency"
|
||||
msgstr "CPU 频率"
|
||||
|
||||
msgid "RAM frequency"
|
||||
msgstr "RAM 频率"
|
||||
|
||||
msgid "Flash Size"
|
||||
msgstr "闪存大小"
|
||||
|
||||
msgid "Free Memory"
|
||||
msgstr "释放内存"
|
||||
|
||||
msgid "RUNNING"
|
||||
msgstr "运行中"
|
||||
|
||||
msgid "NOT RUNNING"
|
||||
msgstr "未运行"
|
||||
|
||||
msgid "ZRam Settings"
|
||||
msgstr "ZRam 设置"
|
||||
|
||||
msgid "ZRam Compression Algorithm"
|
||||
msgstr "ZRam 压缩算法"
|
||||
|
||||
msgid "ZRam Compression Streams"
|
||||
msgstr "ZRam 压缩数据流线程数"
|
||||
|
||||
msgid "ZRam Size"
|
||||
msgstr "ZRam 大小"
|
||||
|
||||
msgid "Size of the ZRam device in megabytes"
|
||||
msgstr "划分给 ZRam 分区的内存大小(MB),推荐留空由系统自动管理"
|
||||
|
||||
msgid "Number of parallel threads used for compression"
|
||||
msgstr "用于压缩内存数据的CPU并发线程数"
|
||||
|
||||
msgid "Swap"
|
||||
msgstr "虚拟内存"
|
||||
|
||||
msgid "Force 40MHz mode"
|
||||
msgstr "强制 40MHz 频宽"
|
||||
|
||||
msgid ""
|
||||
"Always use 40MHz channels even if the secondary channel overlaps. Using this "
|
||||
"option does not comply with IEEE 802.11n-2009!"
|
||||
msgstr "强制启用 40MHz 频宽并忽略辅助信道重叠。此选项可能不兼容某些无线硬件导致无法启用!"
|
||||
|
||||
msgid "Disassociate On Low Acknowledgement"
|
||||
msgstr "弱信号剔除"
|
||||
|
||||
msgid "Allow AP mode to disconnect STAs based on low ACK condition"
|
||||
msgstr "允许 AP 模式基于低 ACK 条件判断剔除弱信号的客户端"
|
||||
|
||||
msgid "Running Status"
|
||||
msgstr "运行状况"
|
||||
|
||||
msgid "Online Users"
|
||||
msgstr "在线用户数"
|
||||
|
||||
msgid "DNS Redirect"
|
||||
msgstr "DNS 重定向"
|
||||
|
||||
msgid "Redirect client DNS to dnsmasq"
|
||||
msgstr "重定向客户端DNS到dnsmasq"
|
||||
|
||||
msgid "Enable 256-QAM"
|
||||
msgstr "启用 256-QAM"
|
||||
|
||||
msgid "802.11n 2.4Ghz Only"
|
||||
msgstr "只适合 802.11n 2.4Ghz"
|
||||
|
||||
msgid "Enables The 802.11k standard provides information to discover the best available access point"
|
||||
msgstr "启用 802.11k 自动寻找发现最佳可用接入点的信息"
|
||||
|
||||
msgid "Enable neighbor report via radio measurements"
|
||||
msgstr "启用无线电测量邻居报告"
|
||||
|
||||
msgid "Enable beacon report via radio measurements"
|
||||
msgstr "启用无线电测量信标报告"
|
||||
|
||||
msgid "Enables 802.11v allows client devices to exchange information about the network topology,tating overall improvement of the wireless network."
|
||||
msgstr "启用 802.11v 将允许客户端设备交换有关网络拓扑的信息,从而全面改善无线网络漫游"
|
||||
|
||||
msgid "extended sleep mode for stations"
|
||||
msgstr "扩展无线休眠节能模式"
|
||||
|
||||
msgid "BSS Transition Management"
|
||||
msgstr "BSS 传输管理"
|
||||
|
||||
msgid "UTC time at which the TSF timer is 0"
|
||||
msgstr "TSF计时器为0的UTC时间"
|
||||
|
||||
msgid "Time advertisement"
|
||||
msgstr "广播同步时间"
|
||||
|
||||
msgid "time zone"
|
||||
msgstr "时区"
|
||||
|
||||
msgid "Local time zone as specified in 8.3 of IEEE Std 1003.1-2004"
|
||||
msgstr "本地时区采用 IEEE Std 1003.1-2004 的 8.3 格式(例如 UTC8)"
|
||||
|
||||
msgid "Custom Redirect Domain"
|
||||
msgstr "自定义挟持域名"
|
||||
|
||||
msgid "Define a custom domain name and the corresponding PTR record"
|
||||
msgstr "自定义域名对应的IP地址(需要客户端DNS指向本路由)"
|
||||
|
||||
msgid "Domain Name"
|
||||
msgstr "域名(不带 HTTP(S)://)"
|
||||
|
||||
msgid "Comments"
|
||||
msgstr "备注"
|
||||
|
||||
msgid "Retain the current packages"
|
||||
msgstr "保留已安装软件包"
|
||||
|
||||
msgid "Packet Steering"
|
||||
msgstr "数据包引导"
|
||||
|
||||
msgid "Enable packet steering across all CPUs. May help or hinder network speed."
|
||||
msgstr "启用所有CPU的数据包控制。 可能有助于或阻碍网络速度。"
|
||||
|
||||
msgid "Disable IPv6 DNS forwards"
|
||||
msgstr "禁止解析 IPv6 DNS 记录"
|
||||
|
||||
msgid "Filter IPv6(AAAA) DNS Query Name Resolve"
|
||||
msgstr "过滤掉 IPv6(AAAA) ,只返回 IPv4 DNS 域名记录"
|
||||
|
||||
msgid "Minimum TTL to send to clients"
|
||||
msgstr "客户端缓存的最小 DNS TTL"
|
||||
|
||||
msgid "Modify DNS entries minimum TTL (max is 86400, 0 is no modify)"
|
||||
msgstr "修改发送到客户端的域名记录的 TTL 时间 (最大 86400, 0 表示不修改)"
|
||||
|
||||
msgid "Firmware Settings"
|
||||
msgstr "固件设置"
|
||||
|
||||
msgid "Packages Auto Upgrade"
|
||||
msgstr "软件包自动更新"
|
||||
|
||||
msgid "Firmware Upgrade Notice"
|
||||
msgstr "固件更新提醒"
|
@ -1,85 +0,0 @@
|
||||
#
|
||||
# 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:=23
|
||||
|
||||
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.baidu.com
|
||||
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))
|
@ -1,5 +0,0 @@
|
||||
|
||||
config gost
|
||||
option enable '0'
|
||||
option run_command ''
|
||||
|
@ -1,22 +0,0 @@
|
||||
#!/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
|
||||
}
|
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
|
42
jpcre2/Makefile
Normal file
42
jpcre2/Makefile
Normal file
@ -0,0 +1,42 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=jpcre2
|
||||
PKG_VERSION:=10.32.01
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE:=$(PKG_NAME)-$(PKG_VERSION).tar.gz
|
||||
PKG_SOURCE_URL:=https://codeload.github.com/jpcre2/jpcre2/tar.gz/$(PKG_VERSION)?
|
||||
PKG_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=BSD 3-Clause
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
|
||||
PKG_BUILD_DEPENDS:=pcre2
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
PKG_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
|
||||
define Package/jpcre2
|
||||
SECTION:=lib
|
||||
CATEGORY:=Libraries
|
||||
TITLE:=C++ wrapper for PCRE2 Library
|
||||
URL:=https://github.com/jpcre2/jpcre2
|
||||
endef
|
||||
|
||||
define Package/jpcre2/description
|
||||
This provides some C++ wrapper classes/functions to perform regex
|
||||
operations such as regex match and regex replace.
|
||||
endef
|
||||
|
||||
define Build/InstallDev
|
||||
$(INSTALL_DIR) $(1)/usr/include
|
||||
$(CP) $(PKG_INSTALL_DIR)/usr/include/jpcre2.hpp $(1)/usr/include/jpcre2.hpp
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,jpcre2))
|
46
libcron/Makefile
Normal file
46
libcron/Makefile
Normal file
@ -0,0 +1,46 @@
|
||||
# SPDX-License-Identifier: GPL-3.0-only
|
||||
#
|
||||
# Copyright (C) 2021 ImmortalWrt.org
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
PKG_NAME:=libcron
|
||||
PKG_VERSION:=1.3.0
|
||||
PKG_RELEASE:=$(AUTORELEASE)
|
||||
|
||||
PKG_SOURCE_PROTO:=git
|
||||
PKG_SOURCE_URL:=https://github.com/PerMalmberg/libcron.git
|
||||
PKG_SOURCE_DATE:=2020-12-04
|
||||
PKG_SOURCE_VERSION:=b0046755bda166dde253e33f68a5b0a1c3ed387e
|
||||
PKG_MIRROR_HASH:=skip
|
||||
|
||||
PKG_LICENSE:=MIT
|
||||
PKG_LICENSE_FILES:=LICENSE
|
||||
PKG_MAINTAINER:=Tianling Shen <cnsztl@immortalwrt.org>
|
||||
|
||||
PKG_BUILD_PARALLEL:=1
|
||||
CMAKE_INSTALL:=1
|
||||
|
||||
include $(INCLUDE_DIR)/package.mk
|
||||
include $(INCLUDE_DIR)/cmake.mk
|
||||
|
||||
define Package/libcron
|
||||
SECTION:=lib
|
||||
CATEGORY:=Libraries
|
||||
URL:=https://github.com/PerMalmberg/libcron
|
||||
TITLE:=A C++ scheduling library using cron formatting
|
||||
endef
|
||||
|
||||
define Package/libcron/description
|
||||
Libcron offers an easy to use API to add callbacks with corresponding cron-formatted strings.
|
||||
endef
|
||||
|
||||
define Build/Install
|
||||
$(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/lib/
|
||||
$(CP) $(PKG_BUILD_DIR)/libcron/out/Release/liblibcron.a $(PKG_INSTALL_DIR)/usr/lib/
|
||||
$(INSTALL_DIR) $(PKG_INSTALL_DIR)/usr/include/libcron/
|
||||
$(CP) $(PKG_BUILD_DIR)/libcron/include/* $(PKG_INSTALL_DIR)/usr/include/
|
||||
$(CP) $(PKG_BUILD_DIR)/libcron/externals/date/include/* $(PKG_INSTALL_DIR)/usr/include/
|
||||
endef
|
||||
|
||||
$(eval $(call BuildPackage,libcron))
|
15
luci-app-amule/Makefile
Normal file
15
luci-app-amule/Makefile
Normal file
@ -0,0 +1,15 @@
|
||||
# Copyright (C) 2016 Openwrt.org
|
||||
#
|
||||
# This is free software, licensed under the Apache License, Version 2.0 .
|
||||
#
|
||||
|
||||
include $(TOPDIR)/rules.mk
|
||||
|
||||
LUCI_TITLE:=LuCI support for Amule
|
||||
LUCI_DEPENDS:=+amule
|
||||
LUCI_PKGARCH:=all
|
||||
|
||||
include $(TOPDIR)/feeds/luci/luci.mk
|
||||
|
||||
# call BuildPackage - OpenWrt buildroot signature
|
||||
|
161
luci-app-amule/luasrc/controller/amule.lua
Normal file
161
luci-app-amule/luasrc/controller/amule.lua
Normal file
@ -0,0 +1,161 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface - amule support
|
||||
|
||||
Copyright 2016 maz-1 <ohmygod19993@gmail.com>
|
||||
|
||||
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
|
||||
]]--
|
||||
|
||||
module("luci.controller.amule", package.seeall)
|
||||
local uci = luci.model.uci.cursor()
|
||||
local configdir = uci:get("amule", "main", "config_dir")
|
||||
|
||||
function index()
|
||||
if not nixio.fs.access("/etc/config/amule") then
|
||||
return
|
||||
end
|
||||
|
||||
entry({"admin", "nas"}, firstchild(), "NAS", 45).dependent = false
|
||||
|
||||
local page = entry({"admin", "nas", "amule"}, cbi("amule"), _("aMule Settings"))
|
||||
page.dependent = true
|
||||
page.acl_depends = { "luci-app-amule" }
|
||||
entry( {"admin", "nas", "amule", "logview"}, call("logread") ).leaf = true
|
||||
entry( {"admin", "nas", "amule", "status"}, call("get_pid") ).leaf = true
|
||||
entry( {"admin", "nas", "amule", "amulecmd"}, call("amulecmd") ).leaf = true
|
||||
entry( {"admin", "nas", "amule", "startstop"}, post("startstop") ).leaf = true
|
||||
entry( {"admin", "nas", "amule", "down_kad"}, post("down_kad") ).leaf = true
|
||||
entry( {"admin", "nas", "amule", "down_ed2k"}, post("down_ed2k") ).leaf = true
|
||||
|
||||
end
|
||||
|
||||
-- called by XHR.get from detail_logview.htm
|
||||
function logread()
|
||||
-- read application settings
|
||||
local uci = luci.model.uci.cursor()
|
||||
local logdir = uci:get("amule", "main", "config_dir") or "/var/run/amule"
|
||||
uci:unload("amule")
|
||||
|
||||
local ldata=nixio.fs.readfile(logdir .. "/logfile")
|
||||
if not ldata or #ldata == 0 then
|
||||
ldata="_nodata_"
|
||||
end
|
||||
luci.http.write(ldata)
|
||||
end
|
||||
|
||||
-- called by XHR.get from detail_startstop.htm
|
||||
function startstop()
|
||||
local pid = get_pid(true)
|
||||
if pid > 0 then
|
||||
luci.sys.call("/etc/init.d/amule stop")
|
||||
nixio.nanosleep(1) -- sleep a second
|
||||
if nixio.kill(pid, 0) then -- still running
|
||||
nixio.kill(pid, 9) -- send SIGKILL
|
||||
end
|
||||
pid = 0
|
||||
else
|
||||
luci.sys.call("/etc/init.d/amule start")
|
||||
nixio.nanosleep(1) -- sleep a second
|
||||
pid = tonumber(luci.sys.exec("pidof amuled")) or 0
|
||||
if pid > 0 and not nixio.kill(pid, 0) then
|
||||
pid = 0 -- process did not start
|
||||
end
|
||||
end
|
||||
luci.http.write(tostring(pid)) -- HTTP needs string not number
|
||||
end
|
||||
|
||||
function down_kad()
|
||||
url = uci:get("amule", "main", "kad_nodes_url")
|
||||
data_path = configdir .. "/nodes.dat"
|
||||
proto = string.gsub(url, "://%S*", "")
|
||||
proto_opt = ( proto == "https" ) and " --no-check-certificate" or ""
|
||||
cmd = "wget -O /tmp/down_nodes.dat \"" .. url .. "\"" .. proto_opt ..
|
||||
" && cat /tmp/down_nodes.dat > " .. "\"" .. data_path .. "\""
|
||||
luci.sys.call(cmd)
|
||||
end
|
||||
|
||||
function down_ed2k()
|
||||
url = uci:get("amule", "main", "ed2k_servers_url")
|
||||
data_path = configdir .. "/server.met"
|
||||
proto = string.gsub(url, "://%S*", "")
|
||||
proto_opt = ( proto == "https" ) and " --no-check-certificate" or ""
|
||||
cmd = "wget -O /tmp/down_server.met \"" .. url .. "\"" .. proto_opt ..
|
||||
" && cat /tmp/down_server.met > " .. "\"" .. data_path .. "\""
|
||||
luci.sys.call(cmd)
|
||||
end
|
||||
|
||||
-- called by XHR.poll from detail_startstop.htm
|
||||
-- and from lua (with parameter "true")
|
||||
function get_pid(from_lua)
|
||||
local pid_amuled = tonumber(luci.sys.exec("pidof amuled")) or 0
|
||||
local amuled_stat =false
|
||||
if pid_amuled > 0 and not nixio.kill(pid_amuled, 0) then
|
||||
pid_amuled = 0
|
||||
end
|
||||
|
||||
if pid_amuled > 0 then
|
||||
amuled_stat =true
|
||||
else
|
||||
amuled_stat =false
|
||||
end
|
||||
|
||||
local pid_amuleweb = tonumber(luci.sys.exec("pidof amuleweb")) or 0
|
||||
local amuleweb_stat = false
|
||||
if pid_amuleweb > 0 and not nixio.kill(pid_amuleweb, 0) then
|
||||
pid_amuleweb = 0
|
||||
end
|
||||
|
||||
if pid_amuleweb > 0 then
|
||||
amuleweb_stat =true
|
||||
else
|
||||
amuleweb_stat =false
|
||||
end
|
||||
|
||||
local status = {
|
||||
amuled = amuled_stat,
|
||||
amuled_pid = pid_amuled,
|
||||
amuleweb = amuleweb_stat
|
||||
}
|
||||
|
||||
if from_lua then
|
||||
return pid_amuled
|
||||
else
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(status)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
function amulecmd()
|
||||
local re =""
|
||||
local rv = { }
|
||||
local cmd = luci.http.formvalue("cmd")
|
||||
local full_cmd = "HOME=\""..configdir.. "\" /usr/bin/amulecmd".." -c \""..cmd.."\" 2>&1"
|
||||
|
||||
local shellpipe = io.popen(full_cmd,"rw")
|
||||
re = shellpipe:read("*a")
|
||||
shellpipe:close()
|
||||
if not re then
|
||||
re=""
|
||||
end
|
||||
|
||||
re = string.gsub(re, "This is amulecmd %S*\n", "")
|
||||
re = string.gsub(re, "Creating client%S*\n", "")
|
||||
re = string.gsub(re, "Succeeded! Connection established to aMule %S*\n", "")
|
||||
|
||||
re = string.gsub(re, "\n", "\r\n")
|
||||
|
||||
rv[#rv+1]=re
|
||||
|
||||
if #rv > 0 then
|
||||
luci.http.prepare_content("application/json")
|
||||
luci.http.write_json(rv)
|
||||
return
|
||||
end
|
||||
|
||||
luci.http.status(404, "No such device")
|
||||
end
|
456
luci-app-amule/luasrc/model/cbi/amule.lua
Normal file
456
luci-app-amule/luasrc/model/cbi/amule.lua
Normal file
@ -0,0 +1,456 @@
|
||||
--[[
|
||||
LuCI - Lua Configuration Interface - Aria2 support
|
||||
|
||||
Copyright 2016 maz-1 <ohmygod19993@gmail.com>
|
||||
]]--
|
||||
|
||||
local sys = require "luci.sys"
|
||||
local util = require "luci.util"
|
||||
local uci = require "luci.model.uci".cursor()
|
||||
|
||||
ptype = {
|
||||
"socks5",
|
||||
"socks4",
|
||||
"http",
|
||||
"socks4a",
|
||||
}
|
||||
|
||||
whocan = {
|
||||
"anyone",
|
||||
"friends",
|
||||
"nobody",
|
||||
}
|
||||
|
||||
function titlesplit(Value)
|
||||
return "<p style=\"font-size:20px;font-weight:bold;color: DodgerBlue\">" .. translate(Value) .. "</p>"
|
||||
end
|
||||
|
||||
m = Map("amule", translate("aMule"), translate("aMule is a ED2K/KAD client for all platforms.") .. "<br/><a href=\"https://github.com/maz-1\">luci interface by maz-1</a>")
|
||||
|
||||
m:section(SimpleSection).template = "amule/overview_status"
|
||||
|
||||
s = m:section(TypedSection, "amule", translate("aMule Settings"))
|
||||
s.addremove = false
|
||||
s.anonymous = true
|
||||
|
||||
s:tab("general", translate("General"))
|
||||
s:tab("connection", translate("Connections"))
|
||||
s:tab("server", translate("Server"))
|
||||
s:tab("path_and_file", translate("Path And File"))
|
||||
s:tab("security", translate("Security"))
|
||||
s:tab("remote", translate("External Control"))
|
||||
s:tab("template", translate("Edit Template"))
|
||||
s:tab("logview", translate("Log File Viewer"))
|
||||
s:tab("amulecmd", translate("aMule command"))
|
||||
|
||||
-- GENERAL --
|
||||
|
||||
o = s:taboption("general", Flag, "enabled", translate("Enabled"))
|
||||
o.rmempty = false
|
||||
|
||||
user = s:taboption("general", ListValue, "runasuser", translate("Run daemon as user"))
|
||||
local p_user
|
||||
for _, p_user in util.vspairs(util.split(sys.exec("cat /etc/passwd | cut -f 1 -d :"))) do
|
||||
user:value(p_user)
|
||||
end
|
||||
|
||||
o = s:taboption("general", Value, "config_dir", translate("Configuration directory"))
|
||||
o.rmempty = false
|
||||
o.placeholder = "/var/run/amule"
|
||||
|
||||
o = s:taboption("general", Value, "mem_percentage", translate("Memory Limit"), translate("Percentage"))
|
||||
o.rmempty = false
|
||||
o.placeholder = "50"
|
||||
o.datatype = "range(1, 99)"
|
||||
|
||||
o = s:taboption("general", Value, "nick", translate("Nickname"))
|
||||
o.placeholder = "http://www.aMule.org"
|
||||
|
||||
o = s:taboption("general", Value, "max_upload", translate("Max upload speed"), translate("Unlimited when set to 0"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = false
|
||||
o.placeholder = "0"
|
||||
|
||||
o = s:taboption("general", Value, "max_download", translate("Max download speed"), translate("Unlimited when set to 0"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = false
|
||||
o.placeholder = "0"
|
||||
|
||||
o = s:taboption("general", Value, "slot_allocation", translate("Slot allocation"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = false
|
||||
o.placeholder = "2"
|
||||
|
||||
o = s:taboption("general", Value, "max_connections", translate("Max connections"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = false
|
||||
o.placeholder = "500"
|
||||
|
||||
o = s:taboption("general", Value, "max_sources_per_file", translate("Max sources per file"))
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = false
|
||||
o.placeholder = "300"
|
||||
|
||||
-- CONNECTIONS --
|
||||
|
||||
o = s:taboption("connection", Value, "port", translate("TCP port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
o.placeholder = "4662"
|
||||
|
||||
o = s:taboption("connection", Flag, "udp_enable", translate("Enable UDP port"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("connection", Value, "udp_port", translate("UDP port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
o.placeholder = "4672"
|
||||
|
||||
o = s:taboption("connection", Flag, "upnp_enabled", translate("Enable UPnP"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("connection", Value, "upnp_tcp_port", translate("UPnP TCP port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = false
|
||||
o.placeholder = "50000"
|
||||
|
||||
o = s:taboption("connection", Value, "address", translate("Bind Address"), translate("Leave blank to bind all"))
|
||||
o.datatype = "ip4addr"
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("connection", Flag, "auto_connect", translate("Automatically connect"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("connection", Flag, "reconnect", translate("Automatically reconnect"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("connection", Flag, "connect_to_kad", translate("Connect to Kad network"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("connection", Flag, "connect_to_ed2k", translate("Connect to ED2K network"))
|
||||
o.rmempty = false
|
||||
|
||||
s:taboption("connection", DummyValue,"titlesplit1" ,titlesplit(translate("Proxy Configuration")))
|
||||
|
||||
o = s:taboption("connection", Flag, "proxy_enable_proxy", translate("Enable proxy"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("connection", ListValue, "proxy_type", translate("Proxy type"))
|
||||
for i,v in ipairs(ptype) do
|
||||
o:value(v)
|
||||
end
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("connection", Value, "proxy_name", translate("Proxy name"))
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("connection", Value, "proxy_port", translate("Proxy port"))
|
||||
o.datatype = "port"
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("connection", Flag, "proxy_enable_password", translate("Proxy requires authentication"))
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("connection", Value, "proxy_user", translate("Proxy user"))
|
||||
--o:depends("proxy_enable_password", "1")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("connection", Value, "proxy_password", translate("Proxy password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
|
||||
-- SERVER --
|
||||
|
||||
o = s:taboption("server", Value, "kad_nodes_url", translate("Kad Nodes Url"), "<input type=\"button\" size=\"0\" title=\""
|
||||
.. translate("Download now") .. "\" onclick=\"onclick_down_kad(this.id)\" "
|
||||
.. "value=\"⥥⥥⥥\" "
|
||||
.. "style=\"font-weight:bold;text-decoration:overline;\""
|
||||
.. "/>")
|
||||
o.rmempty = false
|
||||
o.placeholder = "http://upd.emule-security.org/nodes.dat"
|
||||
|
||||
o = s:taboption("server", Value, "ed2k_servers_url", translate("Ed2k Servers List Url"), "<input type=\"button\" size=\"0\" title=\""
|
||||
.. translate("Download now") .. "\" onclick=\"onclick_down_ed2k(this.id)\" "
|
||||
.. "value=\"⥥⥥⥥\" "
|
||||
.. "style=\"font-weight:bold;text-decoration:overline;\""
|
||||
.. "/>")
|
||||
o.rmempty = false
|
||||
o.placeholder = "http://upd.emule-security.org/server.met"
|
||||
|
||||
o = s:taboption("server", Flag, "remove_dead_server", translate("Remove Dead Server"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Value, "dead_server_retry", translate("Dead Server Retry"))
|
||||
--o:depends("remove_dead_server", "1")
|
||||
o.datatype = "uinteger"
|
||||
o.rmempty = false
|
||||
o.placeholder = "3"
|
||||
o.default = "3"
|
||||
|
||||
o = s:taboption("server", Flag, "add_server_list_from_server", translate("Update server list when connecting to a server"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Flag, "add_server_list_from_client", translate("Update server list when a client connects"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Flag, "scoresystem", translate("Use priority system"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Flag, "smart_id_check", translate("Use smart LowID check on connect"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Flag, "safe_server_connect", translate("Safe connect"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Flag, "auto_connect_static_only", translate("Auto connect to servers in static list only"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Flag, "manual_high_prio", translate("Set manually added servers to high priority"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("server", Flag, "serverlist", translate("Auto update server list at startup"), translate("addresses.dat file"))
|
||||
o.rmempty = false
|
||||
|
||||
addr = s:taboption("server", Value, "addresses", translate("Server addresses"),
|
||||
translate("Content of addresses.dat. One address per line"))
|
||||
addr:depends("serverlist", "1")
|
||||
addr.template = "cbi/tvalue"
|
||||
addr.rows = 5
|
||||
addr.rmempty = true
|
||||
function addr.cfgvalue(self, section)
|
||||
return nixio.fs.readfile("/etc/amule/addresses.dat")
|
||||
end
|
||||
|
||||
function addr.write(self, section, value)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
nixio.fs.writefile("//etc/amule/addresses.dat", value)
|
||||
end
|
||||
|
||||
-- PATH AND FILE --
|
||||
|
||||
o = s:taboption("path_and_file", Value, "temp_dir", translate("Temporary directory"))
|
||||
o.rmempty = false
|
||||
o.placeholder = "/var/run/amule/.aMule/Temp"
|
||||
|
||||
o = s:taboption("path_and_file", Value, "incoming_dir", translate("Incoming directory"))
|
||||
o.rmempty = false
|
||||
o.placeholder = "/var/run/amule/.aMule/Incoming"
|
||||
|
||||
|
||||
shareddir = s:taboption("path_and_file", Value, "shareddir", translate("Shared directory"),
|
||||
translate("Content of shareddir.dat. One directory per line"))
|
||||
shareddir.template = "cbi/tvalue"
|
||||
shareddir.titleref = luci.dispatcher.build_url("admin", "system", "fstab")
|
||||
shareddir.rows = 5
|
||||
shareddir.rmempty = true
|
||||
function shareddir.cfgvalue(self, section)
|
||||
return nixio.fs.readfile("/etc/amule/shareddir.dat")
|
||||
end
|
||||
|
||||
function shareddir.write(self, section, value)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
nixio.fs.writefile("//etc/amule/shareddir.dat", value)
|
||||
end
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "ich", translate("Intelligent corruption handling (I.C.H.)"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "a_ich_trust", translate("Advanced I.C.H trusts every hash (not recommended)"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "add_new_files_paused", translate("Add files to download in pause mode"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "dap_pref", translate("Add files to download with auto priority"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "start_next_file", translate("Start next paused file when a file completes"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "start_next_file_same_cat", translate("Start next paused file from the same category"))
|
||||
o:depends("start_next_file", "1")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "start_next_file_alpha", translate("Start next paused file in alphabetic order"))
|
||||
o:depends("start_next_file", "1")
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "allocate_full_file", translate("Preallocate disk space for new files"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Value, "min_free_disk_space", translate("Minimum free disk space. in Mbytes"))
|
||||
o.datatype = "uinteger"
|
||||
o.placeholder = "1"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "use_src_seed", translate("Save 10 sources on rare files (< 20 sources)"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("path_and_file", Flag, "uap_pref", translate("Add new shares with auto priority"))
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
-- SECURITY --
|
||||
|
||||
|
||||
o = s:taboption("security", Flag, "use_sec_ident", translate("Use secure user identification"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", Flag, "is_crypt_layer_requested", translate("Use obfuscation for outgoing connections"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", Flag, "is_client_crypt_layer_required", translate("Accept only obfuscation connections"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", ListValue, "see_share", translate("Who can see my shared files"))
|
||||
for i,v in ipairs(whocan) do
|
||||
o:value(v)
|
||||
end
|
||||
o.rmempty = false
|
||||
|
||||
s:taboption("security", DummyValue,"titlesplit2" ,titlesplit(translate("IP Filter Configuration")))
|
||||
|
||||
shareddir = s:taboption("security", Value, "ipfilter_static", translate("Static IP list for filtering"),
|
||||
translate("Content of ipfilter_static.dat"))
|
||||
shareddir.template = "cbi/tvalue"
|
||||
shareddir.titleref = luci.dispatcher.build_url("admin", "system", "fstab")
|
||||
shareddir.rows = 5
|
||||
shareddir.rmempty = true
|
||||
function shareddir.cfgvalue(self, section)
|
||||
return nixio.fs.readfile("/etc/amule/ipfilter_static.dat")
|
||||
end
|
||||
|
||||
function shareddir.write(self, section, value)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
nixio.fs.writefile("//etc/amule/ipfilter_static.dat", value)
|
||||
end
|
||||
|
||||
o = s:taboption("security", Flag, "ip_filter_clients", translate("Filter clients by IP"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", Flag, "ip_filter_servers", translate("Filter servers by IP"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", Value, "ip_filter_url", translate("IP filter list URL"))
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("security", Flag, "ip_filter_auto_load", translate("Auto-update ipfilter at startup"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", Value, "filter_level", translate("Filtering Level"))
|
||||
o.datatype = "range(1, 255)"
|
||||
o.rmempty = false
|
||||
o.placeholder = "127"
|
||||
|
||||
o = s:taboption("security", Flag, "filter_lan_ips", translate("Always filter LAN IPs"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", Flag, "paranoid_filtering", translate("Paranoid handling of non-matching IPs"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("security", Flag, "ip_filter_system", translate("Use system-wide ipfilter.dat if available"))
|
||||
o.rmempty = false
|
||||
|
||||
-- REMOTE CONTROL --
|
||||
|
||||
o = s:taboption("remote", Value, "ec_address", translate("IP of the listening interface for external connection"))
|
||||
o.datatype = "ip4addr"
|
||||
o.placeholder = "127.0.0.1"
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("remote", Value, "ec_port", translate("TCP port for EC"))
|
||||
o.datatype = "port"
|
||||
o.placeholder = "4712"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("remote", Flag, "upnp_ec_enabled", translate("Enable upnp port forwarding on the EC port"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("remote", Value, "ec_password", translate("EC password"))
|
||||
o.password = true
|
||||
o.rmempty = false
|
||||
|
||||
s:taboption("remote", DummyValue,"titlesplit3", titlesplit(translate("aMule Web Configuration")))
|
||||
|
||||
o = s:taboption("remote", Flag, "web_enabled", translate("Enable web server on startup"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("remote", Value, "template", translate("Web template"))
|
||||
o.rmempty = false
|
||||
local tpth_suggestions = luci.sys.exec("ls /usr/share/amule/webserver/|sed ':a;N;$!ba;s/\\n/:/g'")
|
||||
if tpth_suggestions then
|
||||
for entry in string.gmatch(tpth_suggestions, "[^:]+") do
|
||||
o:value(entry)
|
||||
end
|
||||
end
|
||||
|
||||
o = s:taboption("remote", Value, "web_password", translate("Web full rights password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("remote", Flag, "use_low_rights_user", translate("Use low rights user"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("remote", Value, "password_low", translate("Web low rights password"))
|
||||
o.password = true
|
||||
o.rmempty = true
|
||||
|
||||
o = s:taboption("remote", Value, "web_port", translate("Web TCP port"))
|
||||
o.datatype = "port"
|
||||
o.placeholder = "4711"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("remote", Flag, "upnp_web_server_enabled", translate("Enable UPnP port forwarding of the web server port"))
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("remote", Value, "web_upnp_tcp_port", translate("Web UPnP TCP port"))
|
||||
o.datatype = "port"
|
||||
o.placeholder = "50001"
|
||||
o.rmempty = false
|
||||
|
||||
o = s:taboption("remote", Value, "page_refresh_time", translate("Page refresh time(in secs)"))
|
||||
o.datatype = "range(1, 600)"
|
||||
o.rmempty = false
|
||||
o.placeholder = "121"
|
||||
|
||||
o = s:taboption("remote", Flag, "use_gzip", translate("Enable Gzip compression"))
|
||||
o.rmempty = false
|
||||
|
||||
|
||||
-- TEMPLATE --
|
||||
|
||||
|
||||
tmpl = s:taboption("template", Value, "_tmpl",
|
||||
translate("Edit the template that is used for generating the aMule configuration."),
|
||||
translate("This is the content of the file '/etc/amule/amule.conf.template' from which your amule configuration will be generated. " ..
|
||||
"Values enclosed by pipe symbols ('|') should not be changed. They get their values from other tabs."))
|
||||
|
||||
tmpl.template = "cbi/tvalue"
|
||||
tmpl.rows = 20
|
||||
|
||||
function tmpl.cfgvalue(self, section)
|
||||
return nixio.fs.readfile("/etc/amule/amule.conf.template")
|
||||
end
|
||||
|
||||
function tmpl.write(self, section, value)
|
||||
value = value:gsub("\r\n?", "\n")
|
||||
nixio.fs.writefile("//etc/amule/amule.conf.template", value)
|
||||
end
|
||||
|
||||
-- LOGVIEW --
|
||||
|
||||
local lv = s:taboption("logview", DummyValue, "_logview")
|
||||
lv.template = "amule/detail_logview"
|
||||
lv.inputtitle = translate("Read / Reread log file")
|
||||
lv.rows = 50
|
||||
|
||||
function lv.cfgvalue(self, section)
|
||||
return translate("Please press [Read] button")
|
||||
end
|
||||
|
||||
-- AMULECMD --
|
||||
|
||||
local cmd = s:taboption("amulecmd", DummyValue, "_amulecmd")
|
||||
cmd.template = "amule/webshell"
|
||||
|
||||
return m
|
56
luci-app-amule/luasrc/view/amule/detail_logview.htm
Normal file
56
luci-app-amule/luasrc/view/amule/detail_logview.htm
Normal file
@ -0,0 +1,56 @@
|
||||
|
||||
<!-- ++ BEGIN ++ aMule ++ detail_logview.htm ++ -->
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
function onclick_logview(section, bottom) {
|
||||
// get elements
|
||||
var txt = document.getElementById("cbid.amule.main._logview.txt"); // TextArea
|
||||
if ( !txt ) { return; } // security check
|
||||
var lvXHR = new XHR();
|
||||
lvXHR.get('<%=url('admin/nas/amule/logview')%>', null,
|
||||
function(x) {
|
||||
if (x.responseText == "_nodata_")
|
||||
txt.value = "<%:File not found or empty%>";
|
||||
else
|
||||
txt.value = x.responseText;
|
||||
if (bottom)
|
||||
txt.scrollTop = txt.scrollHeight;
|
||||
else
|
||||
txt.scrollTop = 0; }
|
||||
);
|
||||
}
|
||||
//]]></script>
|
||||
|
||||
<%+cbi/valueheader%>
|
||||
|
||||
<br />
|
||||
|
||||
<%
|
||||
-- one button on top, one at the buttom
|
||||
%>
|
||||
<input class="btn cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="onclick_logview(this.name, false)"
|
||||
<%=
|
||||
attr("name", section) .. attr("id", cbid .. ".btn1") .. attr("value", self.inputtitle)
|
||||
%> />
|
||||
|
||||
<br /><br />
|
||||
|
||||
<%
|
||||
-- set a readable style taken from openwrt theme for textarea#syslog
|
||||
-- in openwrt theme there are problems with a width of 100 so we check for theme and set to lower value
|
||||
%>
|
||||
<textarea style="width: <%if media == "/luci-static/openwrt.org" then%>98.7%<%else%>100%<%end%> ; min-height: 500px; border: 3px solid #cccccc; padding: 5px; font-family: monospace; resize: none;" wrap="off" readonly="readonly"
|
||||
<%=
|
||||
attr("name", cbid .. ".txt") .. attr("id", cbid .. ".txt") .. ifattr(self.rows, "rows")
|
||||
%> >
|
||||
<%-=pcdata(self:cfgvalue(section))-%>
|
||||
</textarea>
|
||||
<br /><br />
|
||||
|
||||
<%
|
||||
-- one button on top, one at the buttom
|
||||
%>
|
||||
<input class="btn cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="onclick_logview(this.name, true)"
|
||||
<%= attr("name", section) .. attr("id", cbid .. ".btn2") .. attr("value", self.inputtitle) %> />
|
||||
|
||||
<%+cbi/valuefooter%>
|
||||
<!-- ++ END ++ aMule ++ detail_logview.htm ++ -->
|
84
luci-app-amule/luasrc/view/amule/overview_status.htm
Normal file
84
luci-app-amule/luasrc/view/amule/overview_status.htm
Normal file
@ -0,0 +1,84 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
XHR.poll(5, '<%=luci.dispatcher.build_url("admin/nas/amule/status")%>', null,
|
||||
function(x, data) {
|
||||
var tb = document.getElementById('amule_status');
|
||||
var btn = document.getElementById("amule_startstop");
|
||||
var btn_tmpl = '<input class="btn cbi-button cbi-button-apply" id="btn_startstop" style="font-size: 100%;" value="PID: NUMBER"type="button" onclick="onclick_startstop(this.id)">'
|
||||
if (data && tb) {
|
||||
if (data.amuled) {
|
||||
var links = '<em><%:aMule daemon is running.%></em>';
|
||||
if (data.amuleweb) {
|
||||
links += '<input class="cbi-button mar-10" type="button" value="<%:Open aMuleWeb%>" onclick="openwebui();" />';
|
||||
}
|
||||
tb.innerHTML = links;
|
||||
} else {
|
||||
tb.innerHTML = '<em><%:aMule daemon is not running.%></em>';
|
||||
}
|
||||
|
||||
if (data.amuled_pid == "0") {
|
||||
btn.innerHTML = btn_tmpl.replace("PID: NUMBER", "<%:Start aMule%>");
|
||||
} else {
|
||||
btn.innerHTML = btn_tmpl.replace("NUMBER", data.amuled_pid);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
);
|
||||
function _data2elements(x, data) {
|
||||
var btn = document.getElementById("btn_startstop");
|
||||
if ( ! btn ) { return; } // security check
|
||||
if (data.amuled_pid == "0") {
|
||||
btn.value = "<%:Start aMule%>";
|
||||
btn.className = "cbi-button cbi-button-apply";
|
||||
btn.disabled = false;
|
||||
} else {
|
||||
btn.value = "PID: " + data.amuled_pid;
|
||||
btn.className = "cbi-button cbi-button-reset";
|
||||
btn.disabled = false;
|
||||
}
|
||||
}
|
||||
// event handler for start/stop button
|
||||
function onclick_startstop(id) {
|
||||
// do start/stop
|
||||
var btnXHR = new XHR();
|
||||
btnXHR.post('<%=url('admin/nas/amule/startstop')%>', { token: '<%=token%>' },
|
||||
function(x, data) { _data2elements(x, data); }
|
||||
);
|
||||
}
|
||||
// event handler for download files
|
||||
function onclick_down_kad(id) {
|
||||
if(confirm("<%:Existing file will be overwritten, do you really want to proceed?%>"))
|
||||
{
|
||||
var btnXHR = new XHR();
|
||||
btnXHR.post('<%=url('admin/nas/amule/down_kad')%>', { token: '<%=token%>' },
|
||||
function(x) {}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function onclick_down_ed2k(id) {
|
||||
if(confirm("<%:Existing file will be overwritten, do you really want to proceed?%>"))
|
||||
{
|
||||
var btnXHR = new XHR();
|
||||
btnXHR.post('<%=url('admin/nas/amule/down_ed2k')%>', { token: '<%=token%>' },
|
||||
function(x) {}
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
function openwebui(){
|
||||
var url = window.location.host+":<%=luci.sys.exec("uci -q get amule.main.web_port"):gsub("^%s*(.-)%s*$", "%1")%>";
|
||||
window.open('http://'+url,'target','');
|
||||
};
|
||||
//]]>
|
||||
</script>
|
||||
<style>.mar-10 {margin-left: 10px; margin-right: 10px;}</style>
|
||||
<fieldset class="cbi-section">
|
||||
<legend><%:aMule Status%></legend>
|
||||
<p id="amule_status">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
<p id="amule_startstop">
|
||||
<em><%:Collecting data...%></em>
|
||||
</p>
|
||||
</fieldset>
|
90
luci-app-amule/luasrc/view/amule/webshell.htm
Normal file
90
luci-app-amule/luasrc/view/amule/webshell.htm
Normal file
@ -0,0 +1,90 @@
|
||||
<script type="text/javascript">//<![CDATA[
|
||||
|
||||
|
||||
String.prototype.startsWith = function (str){
|
||||
return this.indexOf(str) == 0;
|
||||
};
|
||||
var iwxhr = new XHR();
|
||||
function update_status(e) {
|
||||
if(e!=null && e.keyCode!=13) return false;
|
||||
/*var cmd = document.getElementById("cmd").value;
|
||||
if(cmd.startsWith("cd"))
|
||||
{
|
||||
newpath = cmd.replace("cd","").replace(" ","");
|
||||
if(newpath.startsWith("/")){
|
||||
document.getElementById("currentpath").value = newpath;
|
||||
}else{
|
||||
document.getElementById("currentpath").value += newpath;
|
||||
}
|
||||
cmd="";
|
||||
}*/
|
||||
|
||||
obj = document.getElementById("screen");
|
||||
cmdstr=(document.getElementById("cmd").value).replace(/\s+/g,"")
|
||||
if (cmdstr == "cls" || cmdstr == "clear")
|
||||
{
|
||||
obj = document.getElementById("screen");
|
||||
obj.value = "";
|
||||
document.getElementById("cmd").value = "";
|
||||
return false;
|
||||
}
|
||||
|
||||
iwxhr.get('<%=luci.dispatcher.build_url("admin", "nas", "amule", "amulecmd")%>', {cmd: document.getElementById("cmd").value },
|
||||
function(x, ifc)
|
||||
{
|
||||
obj = document.getElementById("screen");
|
||||
obj.value+=ifc[0];
|
||||
document.getElementById("cmd").focus();
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
|
||||
if ((document.getElementById("cmd").value).replace(/\s+/g,"") != "")
|
||||
{
|
||||
obj.value+="\r\n--------------------------------------------\r\n"+document.getElementById("cmd").value+"\r\n--------------------------------------------\r\n";
|
||||
document.getElementById("cmd").value = "";
|
||||
return false;
|
||||
}
|
||||
};
|
||||
|
||||
function clear_textfield() {
|
||||
obj = document.getElementById("screen");
|
||||
obj.value=""
|
||||
}
|
||||
|
||||
|
||||
//]]></script>
|
||||
|
||||
<style>
|
||||
.cmd_line{
|
||||
background-color:yellow;
|
||||
|
||||
}
|
||||
#list ul li
|
||||
{
|
||||
margin-right:5px;
|
||||
height:16px;
|
||||
display:block;
|
||||
float:left;
|
||||
word-break: keep-all;
|
||||
}
|
||||
#list ul li:hover
|
||||
{
|
||||
background:blue;
|
||||
cursor:pointer;
|
||||
}
|
||||
</style>
|
||||
<div class="cbi-map" id="cbi-system">
|
||||
<h4><a id="content" name="content"><%:You can call amulecmd commands here to control your amule.%></a></h4>
|
||||
<h4><a id="content" name="content"><%:Execute 'Help' to get more infomation.%></a></h4>
|
||||
<textarea id="screen" style="width:100%;height:400px;overflow:auto;font-size:12px;" readonly="readonly" ></textarea>
|
||||
<br/>
|
||||
<%=translate("Command: ")%>
|
||||
<input type="text" id="cmd"/>
|
||||
<input class="btn cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="update_status(null)"
|
||||
<%= attr("name", section) .. attr("id", cbid .. ".btn2") .. attr("value", translate("Execute")) %> />
|
||||
<input class="btn cbi-button cbi-input-button" style="align: center; width: 100%" type="button" onclick="clear_textfield()"
|
||||
<%= attr("name", section) .. attr("id", cbid .. ".btn3") .. attr("value", translate("Clear")) %> />
|
||||
<br/>
|
||||
</div>
|
360
luci-app-amule/po/zh_Hans/amule.po
Normal file
360
luci-app-amule/po/zh_Hans/amule.po
Normal file
@ -0,0 +1,360 @@
|
||||
msgid "aMule is a ED2K/KAD client for all platforms."
|
||||
msgstr "aMule是一个跨平台的ED2K/KAD客户端"
|
||||
|
||||
msgid "NAS"
|
||||
msgstr "网络存储"
|
||||
|
||||
msgid "General"
|
||||
msgstr "常规"
|
||||
|
||||
msgid "Connections"
|
||||
msgstr "连接"
|
||||
|
||||
msgid "Server"
|
||||
msgstr "服务器"
|
||||
|
||||
msgid "Path And File"
|
||||
msgstr "路径和文件"
|
||||
|
||||
msgid "Security"
|
||||
msgstr "安全"
|
||||
|
||||
msgid "External Control"
|
||||
msgstr "远程控制"
|
||||
|
||||
msgid "Edit Template"
|
||||
msgstr "编辑配置模版"
|
||||
|
||||
msgid "Log File Viewer"
|
||||
msgstr "日志查看"
|
||||
|
||||
msgid "aMule Settings"
|
||||
msgstr "aMule设置"
|
||||
|
||||
msgid "Run daemon as user"
|
||||
msgstr "运行守护进程的用户"
|
||||
|
||||
msgid "Configuration directory"
|
||||
msgstr "配置目录"
|
||||
|
||||
msgid "Nickname"
|
||||
msgstr "昵称"
|
||||
|
||||
msgid "Max upload speed"
|
||||
msgstr "最大上传速度"
|
||||
|
||||
msgid "Max download speed"
|
||||
msgstr "最大下载速度"
|
||||
|
||||
msgid "Unlimited when set to 0"
|
||||
msgstr "设为0时不限制"
|
||||
|
||||
msgid "Slot allocation"
|
||||
msgstr "槽速度"
|
||||
|
||||
msgid "Max connections"
|
||||
msgstr "最大连接数"
|
||||
|
||||
msgid "Max sources per file"
|
||||
msgstr "单文件最大连接数"
|
||||
|
||||
msgid "TCP port"
|
||||
msgstr "TCP端口"
|
||||
|
||||
msgid "UDP port"
|
||||
msgstr "UDP端口"
|
||||
|
||||
msgid "Enable UDP port"
|
||||
msgstr "启用UDP端口"
|
||||
|
||||
msgid "Enable UPnP"
|
||||
msgstr "启用UPnP"
|
||||
|
||||
msgid "UPnP TCP port"
|
||||
msgstr "UPnP TCP端口"
|
||||
|
||||
msgid "Bind Address"
|
||||
msgstr "地址绑定"
|
||||
|
||||
msgid "Leave blank to bind all"
|
||||
msgstr "留空则全部绑定"
|
||||
|
||||
msgid "Default to bind all"
|
||||
msgstr "默认全部绑定"
|
||||
|
||||
msgid "Automatically connect"
|
||||
msgstr "自动连接"
|
||||
|
||||
msgid "Automatically reconnect"
|
||||
msgstr "自动重连"
|
||||
|
||||
msgid "Connect to Kad network"
|
||||
msgstr "连接到Kad网络"
|
||||
|
||||
msgid "Connect to ED2K network"
|
||||
msgstr "连接到ED2K网络"
|
||||
|
||||
msgid "Proxy Configuration"
|
||||
msgstr "代理设置"
|
||||
|
||||
msgid "Enable proxy"
|
||||
msgstr "启用代理"
|
||||
|
||||
msgid "Proxy type"
|
||||
msgstr "代理类型"
|
||||
|
||||
msgid "Proxy name"
|
||||
msgstr "代理名称"
|
||||
|
||||
msgid "Proxy port"
|
||||
msgstr "代理端口"
|
||||
|
||||
msgid "Proxy requires authentication"
|
||||
msgstr "代理需要认证"
|
||||
|
||||
msgid "Proxy user"
|
||||
msgstr "代理用户"
|
||||
|
||||
msgid "Proxy password"
|
||||
msgstr "代理密码"
|
||||
|
||||
msgid "Kad Nodes Url"
|
||||
msgstr "Kad节点URL"
|
||||
|
||||
msgid "Ed2k Servers List Url"
|
||||
msgstr "Ed2k服务器列表URL"
|
||||
|
||||
msgid "Remove Dead Server"
|
||||
msgstr "删除无效服务器"
|
||||
|
||||
msgid "Dead Server Retry"
|
||||
msgstr "删除前重连次数"
|
||||
|
||||
msgid "Update server list when connecting to a server"
|
||||
msgstr "与服务器连接时更新服务器列表"
|
||||
|
||||
msgid "Update server list when a client connects"
|
||||
msgstr "与其他用户连接时更新服务器列表"
|
||||
|
||||
msgid "Use priority system"
|
||||
msgstr "启用优先级系统"
|
||||
|
||||
msgid "Use smart LowID check on connect"
|
||||
msgstr "智能LOWID检测"
|
||||
|
||||
msgid "Safe connect"
|
||||
msgstr "安全连接"
|
||||
|
||||
msgid "Auto connect to servers in static list only"
|
||||
msgstr "只自动连接到静态列表中的服务器"
|
||||
|
||||
msgid "Set manually added servers to high priority"
|
||||
msgstr "将手动输入的服务器设为高优先级"
|
||||
|
||||
msgid "Auto update server list at startup"
|
||||
msgstr "启动时自动更新服务器列表"
|
||||
|
||||
msgid "addresses.dat file"
|
||||
msgstr "addresses.dat文件"
|
||||
|
||||
msgid "Server addresses"
|
||||
msgstr "服务器地址"
|
||||
|
||||
msgid "Content of addresses.dat. One address per line"
|
||||
msgstr "addresses.dat的内容. 每行一个地址."
|
||||
|
||||
msgid "Temporary directory"
|
||||
msgstr "临时文件夹"
|
||||
|
||||
msgid "Incoming directory"
|
||||
msgstr "下载文件夹"
|
||||
|
||||
msgid "Shared directory"
|
||||
msgstr "共享文件夹"
|
||||
|
||||
msgid "Content of shareddir.dat. One directory per line"
|
||||
msgstr "shareddir.dat的内容. 每行一个目录."
|
||||
|
||||
msgid "Intelligent corruption handling (I.C.H.)"
|
||||
msgstr "智能损坏数据处理(I.C.H.)"
|
||||
|
||||
msgid "Advanced I.C.H trusts every hash (not recommended)"
|
||||
msgstr "高级I.C.H,信任全部校验值(不推荐)"
|
||||
|
||||
msgid "Add files to download in pause mode"
|
||||
msgstr "添加新下载文件时设为暂停"
|
||||
|
||||
msgid "Add files to download with auto priority"
|
||||
msgstr "添加新下载文件时设定优先级为自动"
|
||||
|
||||
msgid "Start next paused file when a file completes"
|
||||
msgstr "一个文件完成时开始下一个暂停的文件"
|
||||
|
||||
msgid "Start next paused file from the same category"
|
||||
msgstr "从同一分类开始下一个暂停的文件"
|
||||
|
||||
msgid "Start next paused file in alphabetic order"
|
||||
msgstr "根据字母顺序开始下一个暂停的文件"
|
||||
|
||||
msgid "Preallocate disk space for new files"
|
||||
msgstr "为新文件预分配磁盘空间"
|
||||
|
||||
msgid "Minimum free disk space. in Mbytes"
|
||||
msgstr "最低剩余空间,单位MB"
|
||||
|
||||
msgid "Save 10 sources on rare files (< 20 sources)"
|
||||
msgstr "保存稀有文件(少于20个源)的十个源"
|
||||
|
||||
msgid "Add new shares with auto priority"
|
||||
msgstr "添加新共享文件时设优先级为自动"
|
||||
|
||||
msgid "Use secure user identification"
|
||||
msgstr "使用安全用户认证"
|
||||
|
||||
msgid "Use obfuscation for outgoing connections"
|
||||
msgstr "为传出连接使用迷惑协议"
|
||||
|
||||
msgid "Accept only obfuscation connections"
|
||||
msgstr "只接受迷惑协议连接"
|
||||
|
||||
msgid "Who can see my shared files"
|
||||
msgstr "谁可查看我的共享文件"
|
||||
|
||||
msgid "IP Filter Configuration"
|
||||
msgstr "IP过滤设置"
|
||||
|
||||
msgid "Static IP list for filtering"
|
||||
msgstr "静态IP过滤列表"
|
||||
|
||||
msgid "Content of ipfilter_static.dat"
|
||||
msgstr "ipfilter_static.dat的内容"
|
||||
|
||||
msgid "Filter clients by IP"
|
||||
msgstr "过滤用户"
|
||||
|
||||
msgid "Filter servers by IP"
|
||||
msgstr "过滤服务器"
|
||||
|
||||
msgid "IP filter list URL"
|
||||
msgstr "过滤列表URL"
|
||||
|
||||
msgid "Auto-update ipfilter at startup"
|
||||
msgstr "自动更新过滤列表"
|
||||
|
||||
msgid "Filtering Level"
|
||||
msgstr "过滤级别"
|
||||
|
||||
msgid "Always filter LAN IPs"
|
||||
msgstr "总是过滤局域网ip地址"
|
||||
|
||||
msgid "Paranoid handling of non-matching IPs"
|
||||
msgstr "处理不匹配的IP"
|
||||
|
||||
msgid "Use system-wide ipfilter.dat if available"
|
||||
msgstr "可用情况下使用系统级的ipfilter.dat"
|
||||
|
||||
msgid "IP of the listening interface for external connection"
|
||||
msgstr "远程连接监听IP"
|
||||
|
||||
msgid "TCP port for EC"
|
||||
msgstr "远程连接TCP端口"
|
||||
|
||||
msgid "Enable upnp port forwarding on the EC port"
|
||||
msgstr "为远程连接端口启用upnp"
|
||||
|
||||
msgid "aMule Web Configuration"
|
||||
msgstr "aMule Web设置"
|
||||
|
||||
msgid "EC password"
|
||||
msgstr "远程连接密码"
|
||||
|
||||
msgid "Enable web server on startup"
|
||||
msgstr "启动时运行Web服务"
|
||||
|
||||
msgid "Web template"
|
||||
msgstr "Web模版"
|
||||
|
||||
msgid "Web full rights password"
|
||||
msgstr "Web最高权限密码"
|
||||
|
||||
msgid "Use low rights user"
|
||||
msgstr "启用低权限用户"
|
||||
|
||||
msgid "Web low rights password"
|
||||
msgstr "Web低权限密码"
|
||||
|
||||
msgid "Web TCP port"
|
||||
msgstr "Web TCP端口"
|
||||
|
||||
msgid "Enable UPnP port forwarding of the web server port"
|
||||
msgstr "为Web服务端口启用UPnP端口转发"
|
||||
|
||||
msgid "Web UPnP TCP port"
|
||||
msgstr "Web服务UPnP的TCP端口"
|
||||
|
||||
msgid "Page refresh time(in secs)"
|
||||
msgstr "页面刷新周期(秒)"
|
||||
|
||||
msgid "Enable Gzip compression"
|
||||
msgstr "启用Gzip压缩"
|
||||
|
||||
msgid "Edit the template that is used for generating the aMule configuration."
|
||||
msgstr "编辑用来生成aMule设置的模板"
|
||||
|
||||
msgid "This is the content of the file '/etc/amule/amule.conf.template' from which your amule configuration will be generated. Values enclosed by pipe symbols ('|') should not be changed. They get their values from other tabs."
|
||||
msgstr "创建aMule设置的 '/etc/amule/amule.conf.template' 文件的内容。被通道符|包围的值不应该在这里改动,请在其他标签修改这些设置。"
|
||||
|
||||
msgid "Read / Reread log file"
|
||||
msgstr "读取/重载日志文件"
|
||||
|
||||
msgid "Please press [Read] button"
|
||||
msgstr "请点击[读取]按钮"
|
||||
|
||||
msgid "File not found or empty"
|
||||
msgstr "文件不存在或为空"
|
||||
|
||||
msgid "aMule Status"
|
||||
msgstr "aMule状态"
|
||||
|
||||
msgid "Open aMuleWeb"
|
||||
msgstr "打开aMuleWeb"
|
||||
|
||||
msgid "aMule daemon is running."
|
||||
msgstr "aMule守护进程正在运行"
|
||||
|
||||
msgid "aMule daemon is not running."
|
||||
msgstr "aMule守护进程未运行"
|
||||
|
||||
msgid "Start aMule"
|
||||
msgstr "启动aMule"
|
||||
|
||||
msgid "aMule command"
|
||||
msgstr "aMule命令"
|
||||
|
||||
msgid "aMule Command"
|
||||
msgstr "aMule命令"
|
||||
|
||||
msgid "You can call amulecmd commands here to control your amule."
|
||||
msgstr "你可以在这里运行amulecmd命令以控制你的aMule"
|
||||
|
||||
msgid "Execute 'Help' to get more infomation."
|
||||
msgstr "执行'Help'命令以获取更多信息"
|
||||
|
||||
msgid "Execute"
|
||||
msgstr "执行"
|
||||
|
||||
msgid "Clear"
|
||||
msgstr "清空"
|
||||
|
||||
msgid "Command: "
|
||||
msgstr "命令: "
|
||||
|
||||
msgid "Download now"
|
||||
msgstr "立即下载"
|
||||
|
||||
msgid "Existing file will be overwritten, do you really want to proceed?"
|
||||
msgstr "已有文件将被覆盖,是否继续?"
|
||||
|
||||
msgid "Percentage"
|
||||
msgstr "百分比"
|
||||
|
206
luci-app-amule/root/etc/amule/amule.conf.template
Executable file
206
luci-app-amule/root/etc/amule/amule.conf.template
Executable file
@ -0,0 +1,206 @@
|
||||
[eMule]
|
||||
Nick=|NICK|
|
||||
MaxUpload=|MAXUPLOAD|
|
||||
MaxDownload=|MAXDOWNLOAD|
|
||||
SlotAllocation=|SLOTALLOCATION|
|
||||
MaxConnections=|MAXCONNECTIONS|
|
||||
MaxSourcesPerFile=|MAXSOURCESPERFILE|
|
||||
Port=|PORT|
|
||||
UDPPort=|UDPPORT|
|
||||
UDPEnable=|UDPENABLE|
|
||||
UPnPEnabled=|UPNPENABLED|
|
||||
UPnPTCPPort=|UPNPTCPPORT|
|
||||
Address=|ADDRESS|
|
||||
Autoconnect=|AUTOCONNECT|
|
||||
Reconnect=|RECONNECT|
|
||||
ConnectToKad=|CONNECTTOKAD|
|
||||
ConnectToED2K=|CONNECTTOED2K|
|
||||
KadNodesUrl=|KADNODESURL|
|
||||
Ed2kServersUrl=|ED2KSERVERSURL|
|
||||
RemoveDeadServer=|REMOVEDEADSERVER|
|
||||
DeadServerRetry=|DEADSERVERRETRY|
|
||||
AddServerListFromServer=|ADDSERVERLISTFROMSERVER|
|
||||
AddServerListFromClient=|ADDSERVERLISTFROMCLIENT|
|
||||
Scoresystem=|SCORESYSTEM|
|
||||
SmartIdCheck=|SMARTIDCHECK|
|
||||
SafeServerConnect=|SAFESERVERCONNECT|
|
||||
AutoConnectStaticOnly=|AUTOCONNECTSTATICONLY|
|
||||
ManualHighPrio=|MANUALHIGHPRIO|
|
||||
Serverlist=|SERVERLIST|
|
||||
TempDir=|TEMPDIR|
|
||||
IncomingDir=|INCOMINGDIR|
|
||||
ICH=|ICH|
|
||||
AICHTrust=|AICHTRUST|
|
||||
AddNewFilesPaused=|ADDNEWFILESPAUSED|
|
||||
DAPPref=|DAPPREF|
|
||||
StartNextFile=|STARTNEXTFILE|
|
||||
StartNextFileSameCat=|STARTNEXTFILESAMECAT|
|
||||
StartNextFileAlpha=|STARTNEXTFILEALPHA|
|
||||
AllocateFullFile=|ALLOCATEFULLFILE|
|
||||
MinFreeDiskSpace=|MINFREEDISKSPACE|
|
||||
UAPPref=|UAPPREF|
|
||||
SeeShare=|SEESHARE|
|
||||
IPFilterURL=|IPFILTERURL|
|
||||
IPFilterAutoLoad=|IPFILTERAUTOLOAD|
|
||||
FilterLevel=|FILTERLANIPS|
|
||||
FilterLanIPs=|FILTERLANIPS|
|
||||
ParanoidFiltering=|PARANOIDFILTERING|
|
||||
IPFilterSystem=|IPFILTERSYSTEM|
|
||||
|
||||
|
||||
FilterMessages=1
|
||||
FilterAllMessages=0
|
||||
MessagesFromFriendsOnly=0
|
||||
MessageFromValidSourcesOnly=1
|
||||
FilterWordMessages=0
|
||||
MessageFilter=
|
||||
ShowMessagesInLog=1
|
||||
FilterComments=0
|
||||
CommentFilter=
|
||||
|
||||
AppVersion=SVN
|
||||
QueueSizePref=50
|
||||
MaxConnectionsPerFiveSeconds=20
|
||||
ServerKeepAliveTimeout=0
|
||||
CheckDiskspace=1
|
||||
PreviewPrio=0
|
||||
FileBufferSizePref=16
|
||||
OSDirectory=/var/run/amule
|
||||
OnlineSignature=0
|
||||
OnlineSignatureUpdate=5
|
||||
EnableTrayIcon=0
|
||||
MinToTray=0
|
||||
ConfirmExit=1
|
||||
StartupMinimized=0
|
||||
3DDepth=10
|
||||
ToolTipDelay=1
|
||||
ShowOverhead=0
|
||||
ShowInfoOnCatTabs=1
|
||||
VerticalToolbar=0
|
||||
GeoIPEnabled=1
|
||||
VideoPlayer=
|
||||
StatGraphsInterval=3
|
||||
statsInterval=30
|
||||
DownloadCapacity=300
|
||||
UploadCapacity=100
|
||||
StatsAverageMinutes=5
|
||||
VariousStatisticsMaxValue=100
|
||||
ShareHiddenFiles=0
|
||||
AutoSortDownloads=0
|
||||
NewVersionCheck=1
|
||||
AdvancedSpamFilter=1
|
||||
MessageUseCaptchas=1
|
||||
Language=
|
||||
SplitterbarPosition=75
|
||||
YourHostname=
|
||||
DateTimeFormat=%A, %x, %X
|
||||
AllcatType=0
|
||||
ShowAllNotCats=0
|
||||
SmartIdState=0
|
||||
DropSlowSources=0
|
||||
ShowRatesOnTitle=0
|
||||
GeoLiteCountryUpdateUrl=http://geolite.maxmind.com/download/geoip/database/GeoLiteCountry/GeoIP.dat.gz
|
||||
StatsServerName=Shorty's ED2K stats
|
||||
StatsServerURL=http://ed2k.shortypower.dyndns.org/?hash=
|
||||
CreateSparseFiles=1
|
||||
|
||||
[Browser]
|
||||
OpenPageInTab=1
|
||||
CustomBrowserString=
|
||||
|
||||
[Proxy]
|
||||
ProxyEnableProxy=|PROXYENABLEPROXY|
|
||||
ProxyType=|PROXYTYPE|
|
||||
ProxyName=|PROXYNAME|
|
||||
ProxyPort=|PROXYPORT|
|
||||
ProxyEnablePassword=|PROXYENABLEPASSWORD|
|
||||
ProxyUser=|PROXYUSER|
|
||||
ProxyPassword=|PROXYPASSWORD|
|
||||
|
||||
[DLP]
|
||||
CheckModString=1
|
||||
CheckUsername=1
|
||||
CheckUserHash=1
|
||||
CheckHelloTag=1
|
||||
CheckInfoTag=1
|
||||
CheckVeryCDMod=0
|
||||
CheckGhostMod=1
|
||||
|
||||
[ExternalConnect]
|
||||
ECAddress=|ECADDRESS|
|
||||
ECPort=|ECPORT|
|
||||
UPnPECEnabled=|UPNPECENABLED|
|
||||
ECPassword=|ECPASSWORD|
|
||||
UseSrcSeeds=|USESRCSEED|
|
||||
UseSecIdent=|USESECIDENT|
|
||||
IpFilterClients=|IPFILTERCLIENTS|
|
||||
IpFilterServers=|IPFILTERSERVERS|
|
||||
|
||||
AcceptExternalConnections=1
|
||||
ShowProgressBar=1
|
||||
ShowPercent=1
|
||||
TransmitOnlyUploadingClients=0
|
||||
|
||||
[WebServer]
|
||||
Enabled=|WEBENABLED|
|
||||
Template=|TEMPLATE|
|
||||
Password=|WEBPASSWORD|
|
||||
UseLowRightsUser=|USELOWRIGHTSUSER|
|
||||
PasswordLow=|PASSWORDLOW|
|
||||
Port=|WEBPORT|
|
||||
UPnPWebServerEnabled=|UPNPWEBSERVERENABLED|
|
||||
WebUPnPTCPPort=|WEBUPNPTCPPORT|
|
||||
PageRefreshTime=|PAGEREFRESHTIME|
|
||||
UseGzip=|USEGZIP|
|
||||
|
||||
Path=amuleweb
|
||||
|
||||
|
||||
[GUI]
|
||||
HideOnClose=0
|
||||
|
||||
[Razor_Preferences]
|
||||
FastED2KLinksHandler=1
|
||||
|
||||
[SkinGUIOptions]
|
||||
Skin=
|
||||
|
||||
[Statistics]
|
||||
MaxClientVersions=0
|
||||
|
||||
[Obfuscation]
|
||||
IsCryptLayerRequested=|ISCRYPTLAYERREQUESTED|
|
||||
IsClientCryptLayerRequired=|ISCLIENTCRYPTLAYERREQUIRED|
|
||||
IsClientCryptLayerSupported=1
|
||||
CryptoPaddingLenght=254
|
||||
CryptoKadUDPKey=281625462
|
||||
|
||||
[PowerManagement]
|
||||
PreventSleepWhileDownloading=0
|
||||
|
||||
|
||||
[UserEvents]
|
||||
[UserEvents/DownloadCompleted]
|
||||
CoreEnabled=0
|
||||
CoreCommand=
|
||||
GUIEnabled=0
|
||||
GUICommand=
|
||||
[UserEvents/NewChatSession]
|
||||
CoreEnabled=0
|
||||
CoreCommand=
|
||||
GUIEnabled=0
|
||||
GUICommand=
|
||||
[UserEvents/OutOfDiskSpace]
|
||||
CoreEnabled=0
|
||||
CoreCommand=
|
||||
GUIEnabled=0
|
||||
GUICommand=
|
||||
[UserEvents/ErrorOnCompletion]
|
||||
CoreEnabled=0
|
||||
CoreCommand=
|
||||
GUIEnabled=0
|
||||
GUICommand=
|
||||
|
||||
|
||||
[HTTPDownload]
|
||||
URL_1=
|
71
luci-app-amule/root/etc/config/amule
Normal file
71
luci-app-amule/root/etc/config/amule
Normal file
@ -0,0 +1,71 @@
|
||||
|
||||
|
||||
config amule 'main'
|
||||
option enabled '0'
|
||||
option runasuser 'amule'
|
||||
option config_dir '/var/run/amule'
|
||||
option mem_percentage '50'
|
||||
option nice '10'
|
||||
option ionice_flags '-c 3'
|
||||
option nick 'http://www.aMule.org'
|
||||
option max_upload '0'
|
||||
option max_download '0'
|
||||
option slot_allocation '2'
|
||||
option max_connections '500'
|
||||
option max_sources_per_file '300'
|
||||
option port '4662'
|
||||
option udp_enable '1'
|
||||
option udp_port '4672'
|
||||
option upnp_tcp_port '50000'
|
||||
option auto_connect '1'
|
||||
option reconnect '1'
|
||||
option connect_to_kad '1'
|
||||
option connect_to_ed2k '1'
|
||||
option kad_nodes_url 'http://upd.emule-security.org/nodes.dat'
|
||||
option ed2k_servers_url 'http://upd.emule-security.org/server.met'
|
||||
option remove_dead_server '1'
|
||||
option dead_server_retry '3'
|
||||
option scoresystem '1'
|
||||
option smart_id_check '1'
|
||||
option use_sec_ident '1'
|
||||
option is_crypt_layer_requested '1'
|
||||
option ip_filter_clients '1'
|
||||
option ip_filter_servers '1'
|
||||
option ip_filter_auto_load '1'
|
||||
option filter_level '127'
|
||||
option filter_lan_ips '1'
|
||||
option paranoid_filtering '1'
|
||||
option ec_port '4712'
|
||||
option ec_password '12345678'
|
||||
option ich '1'
|
||||
option dap_pref '1'
|
||||
option start_next_file '1'
|
||||
option min_free_disk_space '1'
|
||||
option use_src_seed '1'
|
||||
option temp_dir '/var/run/amule/Temp'
|
||||
option incoming_dir '/var/run/amule/Incoming'
|
||||
option proxy_enable_proxy '0'
|
||||
option add_server_list_from_server '0'
|
||||
option add_server_list_from_client '0'
|
||||
option safe_server_connect '0'
|
||||
option auto_connect_static_only '0'
|
||||
option manual_high_prio '0'
|
||||
option serverlist '0'
|
||||
option a_ich_trust '0'
|
||||
option add_new_files_paused '0'
|
||||
option allocate_full_file '0'
|
||||
option uap_pref '0'
|
||||
option is_client_crypt_layer_required '0'
|
||||
option see_share 'nobody'
|
||||
option ip_filter_system '0'
|
||||
option upnp_ec_enabled '0'
|
||||
option web_enabled '0'
|
||||
option upnp_enabled '0'
|
||||
option proxy_type 'socks5'
|
||||
option template 'default'
|
||||
option use_low_rights_user '0'
|
||||
option web_port '44711'
|
||||
option upnp_web_server_enabled '0'
|
||||
option web_upnp_tcp_port '50001'
|
||||
option page_refresh_time '121'
|
||||
option use_gzip '0'
|
14
luci-app-amule/root/etc/hotplug.d/iface/20-amule
Executable file
14
luci-app-amule/root/etc/hotplug.d/iface/20-amule
Executable file
@ -0,0 +1,14 @@
|
||||
#!/bin/sh
|
||||
# Copyright (C) 2007 OpenWrt.org
|
||||
|
||||
/etc/init.d/amule enabled && {
|
||||
|
||||
[ "$ACTION" = "ifup" ] && {
|
||||
/etc/init.d/amule start
|
||||
}
|
||||
|
||||
[ "$ACTION" = "ifdown" ] && {
|
||||
/etc/init.d/amule stop
|
||||
}
|
||||
|
||||
}
|
179
luci-app-amule/root/etc/init.d/amule
Executable file
179
luci-app-amule/root/etc/init.d/amule
Executable file
@ -0,0 +1,179 @@
|
||||
#!/bin/sh /etc/rc.common
|
||||
# Copyright (C) 2010-2015 OpenWrt.org
|
||||
|
||||
START=99
|
||||
USE_PROCD=1
|
||||
|
||||
|
||||
LIST_SEP="
|
||||
"
|
||||
|
||||
service_triggers() {
|
||||
procd_add_reload_trigger amule
|
||||
}
|
||||
|
||||
unregex() {
|
||||
echo "$1" | sed -e 's/[]\/()$*.^|[]/\\&/g'
|
||||
}
|
||||
|
||||
option_word_to_digit() {
|
||||
word=$(grep -ioE "\b$2=\S+" "$1"|awk -F= '{print $2}')
|
||||
digit=$(echo "$3" |grep -oE "$word/\S+"|awk -F'/' '{print $2}')
|
||||
sed -i "s/\b$2=$word\b/$2=$digit/g" "$1"
|
||||
}
|
||||
|
||||
encrypt_password() {
|
||||
pass_notencryted=$(grep -ioE "\b$2=[^\n]+" "$1"|sed "s/.*$2=//g")
|
||||
pass_encryted=$(echo -n $pass_notencryted|md5sum|grep -oE "[a-z0-9]{32}")
|
||||
[[ -z $pass_notencryted ]] || sed -i "s/\b$2=$(unregex $pass_notencryted)/$2=$pass_encryted/g" "$1"
|
||||
}
|
||||
|
||||
write_dat_file() {
|
||||
if [[ -s "$1" ]] ; then
|
||||
cat "$1" > "$2"
|
||||
else
|
||||
[[ -s "$2" ]] && cat "$2" > "$1"
|
||||
fi
|
||||
}
|
||||
|
||||
set_params() {
|
||||
cat /etc/amule/amule.conf.template > "$config_file"
|
||||
local p; local v; local s="$1"; shift
|
||||
for p in $*; do
|
||||
config_get v "$s" "$p"
|
||||
IFS="$LIST_SEP"
|
||||
for v in $v; do
|
||||
[ -n "$v" ] && (
|
||||
sed -i "s;|$(echo $p|tr '[a-z]' '[A-Z]'|sed -e 's|_||g')|;$(unregex $v);g" "$config_file"
|
||||
)
|
||||
done
|
||||
unset IFS
|
||||
done
|
||||
|
||||
#delete unreplaced placeholders
|
||||
sed -i "s;=|[A-Z0-9]*|;=;g" "$config_file"
|
||||
|
||||
#convert some options to digit
|
||||
option_word_to_digit "$config_file" "ProxyType" "socks5/0 socks4/1 http/2 socks4a/3"
|
||||
option_word_to_digit "$config_file" "SeeShare" "anyone/0 friends/1 nobody/2"
|
||||
|
||||
#encrypt password
|
||||
encrypt_password "$config_file" "ECPassword"
|
||||
encrypt_password "$config_file" "Password"
|
||||
encrypt_password "$config_file" "PasswordLow"
|
||||
}
|
||||
|
||||
section_enabled() {
|
||||
config_get_bool enabled "$1" 'enabled' 0
|
||||
[ $enabled -gt 0 ]
|
||||
}
|
||||
|
||||
set_owner() {
|
||||
case $(echo "$1"|grep -oE "^/[^/]+") in
|
||||
"/var"|"/tmp"|"/mnt"|"root")
|
||||
cur_user=$(ls -w50 -ld "$1"|awk '{print $3}')
|
||||
cur_group=$(ls -w50 -ld "$1"|awk '{print $4}')
|
||||
[[ $cur_user == $2 ]] || ( chown -R $2 "$1" )
|
||||
[[ $cur_group == $3 ]] || ( chgrp -R $3 "$1" )
|
||||
;;
|
||||
*)
|
||||
false
|
||||
;;
|
||||
esac
|
||||
}
|
||||
|
||||
amule() {
|
||||
local cfg="$1"
|
||||
local USE
|
||||
|
||||
local runasuser
|
||||
local incoming_dir config_dir temp_dir
|
||||
local mem_percentage
|
||||
local config_overwrite nice ionice_flags
|
||||
local cmdline
|
||||
|
||||
section_enabled "$section" || return 1
|
||||
|
||||
config_get config_dir "$cfg" 'config_dir' '/var/run/amule'
|
||||
config_get runasuser "$cfg" 'runasuser' 'daemon'
|
||||
config_get incoming_dir "$cfg" 'incoming_dir' "$config_dir/Incoming"
|
||||
config_get temp_dir "$cfg" 'temp_dir' "$config_dir/Temp"
|
||||
config_get mem_percentage "$cfg" 'mem_percentage' '50'
|
||||
config_get config_overwrite "$cfg" config_overwrite 1
|
||||
config_get nice "$cfg" nice "-19"
|
||||
config_get ionice_flags "$cfg" ionice_flags ''
|
||||
group=$(id -Gn $runasuser)
|
||||
|
||||
case $(echo "$config_dir"|grep -oE "^/[^/]+") in
|
||||
"/var"|"/tmp"|"/mnt"|"/root"|"/home")
|
||||
true
|
||||
;;
|
||||
*)
|
||||
echo "You should set config_dir to subfolders under /var, /tmp ,/mnt or /root"
|
||||
return 1
|
||||
;;
|
||||
esac
|
||||
|
||||
which ionice > /dev/null || ionice_flags=''
|
||||
|
||||
local MEM=$(sed -ne 's!^MemTotal:[[:space:]]*\([0-9]*\) kB$!\1!p' /proc/meminfo)
|
||||
if test "$MEM" -gt 1;then
|
||||
USE=$(expr $MEM \* $mem_percentage \* 10)
|
||||
fi
|
||||
|
||||
config_file="$config_dir/amule.conf"
|
||||
#[ -d "$config_dir" ] || {
|
||||
mkdir -m 0755 -p "$config_dir"
|
||||
chmod g+s "$config_dir"
|
||||
chown $group:$runasuser "$config_dir"
|
||||
touch "$config_file" "$config_dir/addresses.dat" "$config_dir/shareddir.dat" \
|
||||
"$config_dir/ipfilter_static.dat"
|
||||
[ -d "$config_dir/.aMule" ] || ln -s ./ $config_dir/.aMule
|
||||
#[ -z "$runasuser" ] || set_owner "$config_dir" $runasuser $group
|
||||
#}
|
||||
|
||||
|
||||
touch "$config_file"
|
||||
write_dat_file /etc/amule/addresses.dat "$config_dir/addresses.dat"
|
||||
write_dat_file /etc/amule/shareddir.dat "$config_dir/shareddir.dat"
|
||||
write_dat_file /etc/amule/ipfilter_static.dat "$config_dir/ipfilter_static.dat"
|
||||
|
||||
#[ "$config_overwrite" == 0 ] || {
|
||||
set_params "$cfg" $(uci show amule|awk -F'[.=]' '{print $3}'|tr '\n' ' ')
|
||||
#}
|
||||
|
||||
HOME="$config_dir" /usr/bin/amulecmd --create-config-from="$config_file"
|
||||
|
||||
cmdline="/usr/bin/amuled -c $config_dir"
|
||||
[ "$ionice_flags" ] && cmdline="ionice $ionice_flags $cmdline"
|
||||
procd_open_instance
|
||||
procd_set_param command $cmdline
|
||||
procd_set_param respawn retry=60
|
||||
procd_set_param user "$runasuser"
|
||||
procd_set_param nice "$nice"
|
||||
if test -z "$USE";then
|
||||
procd_set_param limits core="0 0"
|
||||
else
|
||||
procd_set_param limits core="0 0" as="$USE $USE"
|
||||
logger -t amule "Starting with $USE virt mem"
|
||||
fi
|
||||
|
||||
procd_add_jail amule log
|
||||
procd_add_jail_mount_rw $config_file
|
||||
procd_add_jail_mount_rw $incoming_dir
|
||||
procd_add_jail_mount_rw $temp_dir
|
||||
procd_close_instance
|
||||
}
|
||||
|
||||
start_service() {
|
||||
killall -9 amuleweb >/dev/null 2>&1
|
||||
config_load 'amule'
|
||||
config_foreach amule 'amule'
|
||||
}
|
||||
|
||||
restart() {
|
||||
stop
|
||||
sleep 2
|
||||
start
|
||||
}
|
||||
|
25
luci-app-amule/root/etc/uci-defaults/luci-amule
Executable file
25
luci-app-amule/root/etc/uci-defaults/luci-amule
Executable file
@ -0,0 +1,25 @@
|
||||
#!/bin/sh
|
||||
|
||||
uci -q batch <<-EOF >/dev/null
|
||||
delete ucitrack.@amule[-1]
|
||||
add ucitrack amule
|
||||
set ucitrack.@amule[-1].init=amule
|
||||
commit ucitrack
|
||||
EOF
|
||||
|
||||
while [ ! $(grep -e "amule" ${IPKG_INSTROOT}/etc/passwd) ]
|
||||
do
|
||||
gid=$(awk -v min=1000 -v max=1500 'BEGIN{srand(); print int(min+rand()*(max-min+1))}')
|
||||
echo amule:x:0:0:99999:7::: >> ${IPKG_INSTROOT}/etc/shadow
|
||||
grep -e ":$gid:" ${IPKG_INSTROOT}/etc/passwd || ( \
|
||||
echo "amule:x:$gid:amule" >> ${IPKG_INSTROOT}/etc/group ; \
|
||||
echo "amule:x:$gid:$gid:amule:/var/run/amule:/bin/false" >> ${IPKG_INSTROOT}/etc/passwd )
|
||||
done
|
||||
|
||||
mkdir -p ${IPKG_INSTROOT}/etc/amule/
|
||||
touch ${IPKG_INSTROOT}/etc/amule/addresses.dat
|
||||
touch ${IPKG_INSTROOT}/etc/amule/ipfilter_static.dat
|
||||
touch ${IPKG_INSTROOT}/etc/amule/shareddir.dat
|
||||
|
||||
rm -f /tmp/luci-indexcache
|
||||
exit 0
|
11
luci-app-amule/root/usr/share/rpcd/acl.d/luci-app-amule.json
Normal file
11
luci-app-amule/root/usr/share/rpcd/acl.d/luci-app-amule.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"luci-app-amule": {
|
||||
"description": "Grant UCI access for luci-app-amule",
|
||||
"read": {
|
||||
"uci": [ "amule" ]
|
||||
},
|
||||
"write": {
|
||||
"uci": [ "amule" ]
|
||||
}
|
||||
}
|
||||
}
|
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
|
||||

|
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);
|
||||
}
|
||||
}
|
||||
}'
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user