找回密码
 立即注册

QQ登录

只需一步,快速开始

搜索
广告投放联系QQ68610888
查看: 16245|回复: 27

凑个热闹,分析下Padavan的代码,一

[复制链接]
Padavan固件研究
一、添加pppoe拔号时lcp echo 开启/关闭 选项
刚开始使用Padavan时,看一看路由器日志,发现里面全部是pppoe已边接,pppoe已断开连接,不断的断线重拔,跳开路由器,换成电脑拔号,不掉线,想应该是路由器器问题,然后百度一下,原来很多华硕路由器都是这样,解释如下:
lcp echo 是pppoe连接协议里的一个环节,连接建立好之后,每隔一个时间,客户端或者服务器,会发送一个叫 lcp echo request 的包,收到的一方会回应一个 lcp echo response 的包,以确定双方都在线,如果多少次发送lcp echo request 而没有收到 lcp echo response 就会认为对方不在线,断开连接。这时就有两个参数来确定 lcp echo :lcp-echo-interval,lcp-echo-failure。这两个值一个是发送间隔时间,一个失败重试次数。华硕固件是默认开启 lcp echo 的,并且lcp-echo-interval=20(单位是秒),lcp-echo-failure=6(次)。算下来就是20*6=120s=2分钟,对方没有回应就断线重连。
本来是pppoe协议的一部分,也没错,但国内很多ISP不知道为了啥,是不主动发送 lcp echo ,也不回应 lcp echo,这就造成了不断的断线重连。就是开始说的那样,有和我一样经历的可以看看Padavan的日志,看看每次边接在断开的时间是2分钟。
找到问题了,那怎么解决呢?继续百度,发现:openwrt 里面,/tmp/ppp/options.wan0 这个文件里存的是pppoe拔号参数,把里面的lcp-echo-interval=20,lcp-echo-failure=6,删掉,或者注释掉就可以了,但是这方面对Padavan里,好像不行,重启或者重连拔号,这个文件会重置的,55555555555555
怎么办,padavan 给我们的办法是:lcp-echo-adaptive 这个参数,意思是自动适配lcp-echo-interval,lcp-echo-failure。就是WAN设置里面的自动LCP响应间隔,我的开启后是24小时断线重接一次,可以接受了,不知道大家的是多少。那怎么完全解决呢,方法只有一个,让padavan生成的/tmp/ppp/options.wan0 文件,本身就没有lcp-echo-interval=20,lcp-echo-failure=6 这两个参数。或者参数自己定。

二、开始分析吧,
反正Padavan是开源的,多读源码总是有发现,我也不知道读了多少,发现这几个文件夹的东西很重要,/user下,shared,rc,httpd,看看目录下Makefile。
这是Shared的:
ifndef ROOTDIR
ROOTDIR=../..
endif
include boards.mk
include cflags.mk
CFLAGS += -fPIC
CFLAGS += -Wall -I. -I./include -I$(ROOTDIR)/$(LINUXDIR)/include/nvram
LDFLAGS += -L.
OBJS := shutils.o netutils.o rtutils.o defaults.o nvram_linux.o notify_rc.o bin_sem_asus.o flash_mtd.o pids.o

all: libshared.so  //看这里,这个文件夹的会编译成一人lib库,

libshared.so: $(OBJS)
        $(LD) -shared -o $@ $^
romfs:
        $(ROMFSINST) -S /lib/libshared.so  //放在路由器的这里。
clean:
        rm -f *.o libshared.so
所以说,这个文件夹里的会编译成一个共享库,都有什么共享资源呢,继续看代码,
defaults.c这个文件,就两个数组:(对,字面上理解,就是默认参数,一些常用的参数,可以在defaults.h里面定义)
struct nvram_pair router_defaults[]
struct nvram_pair tables_defaults[]
在nvram_linux.h里面,有struct nvram_pair的定义:
struct nvram_pair {
        char *name;
        char *value;
};//就是两个数据,一个名称,一个值,所以上面的libshared.so里面,是包含所有的nvram 的默认参数表的,路由器的所有参数,也是存在nvram里面,所以,要添加pppoe拔号时lcp echo 开启/关闭 选项,我们就要在这里面加个开关选项的参数是吧,{ "wan_ppp_alcp", "1" },//这是自动LCP响应间隔的参数名,那我就取个wan_ppp_lcp吧,大家想取什么都行,自已好理解就行。
nvram_linux.c里定义了nvram操作的各个函数,
extern char *nvram_get(const char *name);
extern char *nvram_safe_get(const char *name);
extern int nvram_get_int(const char *name);
extern int nvram_safe_get_int(const char* name, int val_def, int val_min, int val_max);
extern int nvram_getall(char *buf, int count, int include_temp);
extern int nvram_set(const char *name, const char *value);
extern int nvram_set_int(const char *name, int value);
extern int nvram_unset(const char *name);
extern int nvram_set_temp(const char *name, const char *value);
extern int nvram_set_int_temp(const char *name, int value);
extern int nvram_match(const char *name, char *match);
extern int nvram_invmatch(const char *name, char *invmatch);
extern int nvram_commit(void);
extern int nvram_clear(void);
上面这些是函数原型,extern 这个参数的意思是导出符号表,别的程序能调用,在Padavan里,所有与nvram操作相关的,都是是调用libshared.so里的这些函数。所以shared这个名字真的没有取错。

看完shared我们再来看rc文件夹,这个更是路由器的总管,我想,rc = router control,嗯,就是这个意思,路由控制。同样先看Makefile
。。。
romfs:
        $(ROMFSINST) /sbin/$(EXEC)
        cd $(INSTALLDIR) && rm -f init && ln -sf sbin/rc init
        cd $(INSTALLDIR)/sbin && ln -sf rc init
        cd $(INSTALLDIR)/sbin && ln -sf rc watchdog
        cd $(INSTALLDIR)/sbin && ln -sf rc hotplug
        cd $(INSTALLDIR)/sbin && ln -sf rc shutdown
        cd $(INSTALLDIR)/sbin && ln -sf rc halt
        cd $(INSTALLDIR)/sbin && ln -sf rc reboot
        cd $(INSTALLDIR)/sbin && ln -sf rc mtk_gpio
        cd $(INSTALLDIR)/sbin && ln -sf rc ddns_updated
        cd $(INSTALLDIR)/sbin && ln -sf rc ntpc_updated
        cd $(INSTALLDIR)/sbin && ln -sf rc start_ddns
        cd $(INSTALLDIR)/sbin && ln -sf rc restart_dns
        cd $(INSTALLDIR)/sbin && ln -sf rc restart_dhcpd
        cd $(INSTALLDIR)/sbin && ln -sf rc restart_v p n_server
        cd $(INSTALLDIR)/sbin && ln -sf rc restart_v p n_client
        cd $(INSTALLDIR)/sbin && ln -sf rc run_telnetd
        cd $(INSTALLDIR)/sbin && ln -sf rc restart_firewall
        cd $(INSTALLDIR)/sbin && ln -sf rc pids
        cd $(INSTALLDIR)/sbin && ln -sf rc rstats
        cd $(INSTALLDIR)/sbin && ln -sf rc stop_wan
        cd $(INSTALLDIR)/sbin && ln -sf rc restart_wan
        cd $(INSTALLDIR)/sbin && ln -sf rc restart_networkmap
        cd $(INSTALLDIR)/sbin && ln -sf rc detect_link
        cd $(INSTALLDIR)/sbin && ln -sf rc detect_internet
        cd $(INSTALLDIR)/sbin && ln -sf rc detect_wan
        cd $(INSTALLDIR)/sbin && ln -sf rc reset_to_defaults
        cd $(INSTALLDIR)/sbin && ln -sf rc lan_eeprom_mac
        cd $(INSTALLDIR)/sbin && ln -sf rc wan_eeprom_mac
        cd $(INSTALLDIR)/sbin && ln -sf rc leds_front
        cd $(INSTALLDIR)/sbin && ln -sf rc leds_ether
。。。这是一部分,里面全是软连接,和busybox有的一拼。现在更确定了吧,所有的路由操作都是rc这个程序在执行,包括init。router control 没错。stop_wan  restart_wan这两个是WAN用的,我们从main函数找一找入口。main在rc.c里面,太长了,中间有一段:
        else if (!strcmp(base, "restart_wan")) {
                notify_rc("manual_wan_reconnect");
        }
再顺着notify_rc()这个函数(这函数在libshared.so里,shared/notify_rc.c),这里有一个通知和信号的处理,最后又是init(也就是rc的init段)处理的,这里我也没完全看懂,毕竟不是计算机专业,也是门外汉,等我把linux的信号处理机制看完再详细说。。。。。
最终绕了一圈,指向这个函数:int launch_wan_pppd(int unit, int wan_proto),在rc/net_ppp.c里面,运行pppd,(不知道pppd与pppoe关系的自己百度),说下流程:
1、打开/tmp/ppp/options.wan0文件,//ps:最后面的0是端口定义,还有个net_wan.c文件里会根据wan的配置及端口定义,生成一个新的含端口的配置参数,也保存在nvram里面,比如,我们开始新加了一个参数,wan_ppp_lcp,net_wan.c里面的void reset_wan_vars(void)函数会生成一个新的参数wan0_ppp_lcp。所以net_wan.c里面也要加一句的:set_wan_unit_param(unit, "ppp_lcp");
2、根据nvram里面的参数,生成/tmp/ppp/options.wan0的内容,保存,退出。
3、执行eval("/usr/sbin/pppd", "file", options);开始拔号,里面的file就是/tmp/ppp/options.wan0罗。
我们要做的,就是修改第二步,根据nvram内容,选择是否生成lcp-echo-interval=20,lcp-echo-failure=6,看代码:
        fprintf(fp, "lcp-echo-interval %d\n", 20);
        fprintf(fp, "lcp-echo-failure %d\n", 6);
        if (get_wan_unit_value_int(unit, "ppp_alcp") > 0)
                fprintf(fp, "lcp-echo-adaptive\n");
看到了吧,Padavan的方法也真是简单粗暴啊,默认写这两个参数,值都还是固定的,20*6,我们先改成:
        if (get_wan_unit_value_int(unit, "ppp_lcp") > 0) {
                fprintf(fp, "lcp-echo-interval %d\n", 60);
                fprintf(fp, "lcp-echo-failure %d\n", 6);
        }
        if (get_wan_unit_value_int(unit, "ppp_alcp") > 0)
                fprintf(fp, "lcp-echo-adaptive\n");
这样就有选项开关了,如果有谁想更定置参数,再加两个参数项:lcp-echo-interval,lcp-echo-failure,让这两个值也能按自己的意思改,我就不改了,我只想关了这个东西。
现在就可以了,目的达到了,我们可以先用nvram命令,生成一个ppp_lcp:nvram set wan0_ppp_lcp=0,就不会断线了,nvram set wan0_ppp_lcp=1,就恢复原样了。不错吧。。。。。。。。。。。。哈。。。。。。。

不过到这,故事只到了一半,,,,我们不能总用命令改啊,我们要用设置网页改。继续读代码,read the fuck source!

到了第三个文件夹,httpd,,,从字面上,这是一个http服务器,但你打开/www下的网页代码,发现没,根本就不是标准的asp代码,唉,又是高度定制啊,

关于http,又是一个很长的故事,明天写吧,要睡觉了。改个值,还要分析后端流程,网页前端,以及POST的过程,

剧透下,httpd里面又有一个参数总表,哈。。。。。。。。。。。。

先打包个改后的文件,网而前端的忘打包了,明天再发,上夜班,回不去。。。。。。。。

















评分

参与人数 2恩山币 +2 收起 理由
云海*** + 1 亲,你这么厉害,我想做你的经纪人!
cix*** + 1 楼主你是大神级小小菜鸟啊还是小小菜鸟级大神啊,哈哈

查看全部评分

我的恩山、我的无线 The best wifi forum is right here.
 楼主| | 显示全部楼层
本帖最后由 lostlonger 于 2017-4-20 20:10 编辑

今天接着写完吧,httpd是一个http服务器,关于这方面,知识太多了,要自己先学学的。说说前端与http互交吧。好在以前上大学时还写过网页,没忘完,用的DIV+CSS布局,asp内容

Padavan的内容主要是设置参数,所以就要用提交表单,在html里面,是<form></form>标签。提交的方法有post 和 get ,看代码:
Advanced_WAN_Content.asp里面:
<iframe name="hidden_frame" id="hidden_frame" src="" width="0" height="0" frameborder="0"></iframe>
<form method="post" name="form" id="ruleForm" action="/start_apply.htm" target="hidden_frame">//响应这个post提交的页面是/start_apply.htm,在hidden_frame里响应,看上面的那句,就是那个iframe name="hidden_frame" ,这有什么用呢,不用重新刷新网页。哈哈。
我们就在form里面加个选项吧。在这个前面加:
                                        <tr>
                                            <th><#PPP_AdaptiveLCP#></th>
                                            <td>
                                                <label class="radio inline"><input type="radio" value="1" name="wan_ppp_alcp" class="input" <% nvram_match_x("", "wan_ppp_alcp", "1", "checked"); %>><#checkbox_Yes#></label>
                                                <label class="radio inline"><input type="radio" value="0" name="wan_ppp_alcp" class="input" <% nvram_match_x("", "wan_ppp_alcp", "0", "checked"); %>><#checkbox_No#></label>
                                            </td>
                                        </tr>

加上后改成:
                                        <tr>
                                            <th><#PPP_LCP#></th>
                                            <td>
                                                <label class="radio inline"><input type="radio" value="1" name="wan_ppp_lcp" class="input" <% nvram_match_x("", "wan_ppp_lcp", "1", "checked"); %>><#checkbox_Yes#></label>
                                                <label class="radio inline"><input type="radio" value="0" name="wan_ppp_lcp" class="input" <% nvram_match_x("", "wan_ppp_lcp", "0", "checked"); %>><#checkbox_No#></label>
                                            </td>
                                        </tr>

                                        <tr>
                                            <th><#PPP_AdaptiveLCP#></th>
                                            <td>
                                                <label class="radio inline"><input type="radio" value="1" name="wan_ppp_alcp" class="input" <% nvram_match_x("", "wan_ppp_alcp", "1", "checked"); %>><#checkbox_Yes#></label>
                                                <label class="radio inline"><input type="radio" value="0" name="wan_ppp_alcp" class="input" <% nvram_match_x("", "wan_ppp_alcp", "0", "checked"); %>><#checkbox_No#></label>
                                            </td>
                                        </tr>

#PPP_LCP#要在语言字典里修改相应的中文哦。
这是最简单的,想要换成像开关那样的风格,自己改javascript吧,我就不详细说,可以参考我的修改。

下面继续看响应的页面start_apply.htm吧。
看重点,执行了这三个函数:
<% update_variables(); %>//更新参数,会执行user\httpd\web_ex.c里的update_variables_ex()
<% asus_nvram_commit(); %>//更新nvram
<% notify_services(); %>//通知相应服务重启


在user\httpd\variables.c里面,定义了一堆参数集,struct variable variables_PPPConnection[]里面是与pppd相关的,我们加一项,{"wan_ppp_alcp", "", NULL, EVM_RESTART_WAN},这样可以了,

具体细节就不多说了,我也还要慢慢看,但改个什么参数啥的没问题了,我修改好的文件在附件里


说下rc的init过程:
/* Basic initialization */
init_time();
dev_init.sh   //建立环境文件,执行 启动脚本-初始化,就是自定义设置-》脚本-》[url=]在路由器初始化前执行:[/url]
init_nodes();
init_mdev();
init_sysctl();
/* Setup console */
/* Setup shell environment */
/* Make sure environs is set to something sane */
/* Setup signal handlers */
/* block SIGUSR1 during init_router() */
/* block SIGUSR2 during notify_shutdown() */
/* Router init and start */          //执行启动后脚本,就是自定义设置-》脚本-》[url=]在路由器启动后执行:[/url]
/* unblock SIGUSR1 */
/* Loop forever */



差不多就这样了,接下来我会改一改网页前端吧,哈,改成不错的再和大家分享


本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

×
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

欢迎原创,顶你!!
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

来自手机 | 显示全部楼层
分析的挺好理解,跟楼主学习
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

来自手机 | 显示全部楼层
太高深了,帮定
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

来自手机 | 显示全部楼层
很好的教程!顶一个!
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

最近想自己解决H大3700v5固件无2.4G的问题

编译了纯净版是可以用2.4G了,但想用H大的SS+KCPTUN,不会集成,看了楼主的文章有点启发
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

一脸懵逼进来。然后一脸懵逼的出去
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

大神,可不可以研究下集成SS+KCPTUN的方法?
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| 来自手机 | 显示全部楼层
就集成SS+KCPTUN这两个程序不难,不过要让页面上配置要新建个网页啊,Padavan是基于bootstrap框架的。可以学着写个页面。只是我现在没fan greatwall的需求,也没ss账号,我要看外面的世界都是临时用下蓝灯
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

网页可以借用下成熟固件的

点评

受之于鱼,不如授之于渔,我说出我分析出的心得,已及怎么修改,加功能的方法,大家可以自己动手。 有时间我也帮助改,不过我不作任何保证哦,没时间啊,唉,。。。。。。  详情 回复 发表于 2017-4-20 20:14
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| | 显示全部楼层
ramonde 发表于 2017-4-20 18:30
网页可以借用下成熟固件的

受之于鱼,不如授之于渔,我说出我分析出的心得,已及怎么修改,加功能的方法,大家可以自己动手。

有时间我也帮助改,不过我不作任何保证哦,没时间啊,唉,。。。。。。

点评

这个可以有,我看了variables.c,里面的函数在加SS时应该增加或怎么命名定义  详情 回复 发表于 2017-4-20 22:43
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

 楼主| | 显示全部楼层
对了,我的虚拟机上,ipset总是编译不过,在configuer时就错误,下最新的,用宿主的gcc也通不过,不知道为啥,谁知道?????????????
libtoolize: putting auxiliary files in AC_CONFIG_AUX_DIR, 'build-aux'.
libtoolize: copying file 'build-aux/ltmain.sh'
libtoolize: putting macros in AC_CONFIG_MACRO_DIRS, 'm4'.
libtoolize: copying file 'm4/libtool.m4'
libtoolize: copying file 'm4/ltargz.m4'
libtoolize:   error: '/usr/share/aclocal/ltdl.m4' does not exist.
autoreconf: libtoolize failed with exit status: 1
谁懂啊?

点评

提示不存在/usr/share/aclocal/ltdl.m4,百度了install libltdl7-dev  详情 回复 发表于 2017-4-20 22:50
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

来自手机 | 显示全部楼层
lostlonger 发表于 2017-4-20 20:18
对了,我的虚拟机上,ipset总是编译不过,在configuer时就错误,下最新的,用宿主的gcc也通不过,不知道为 ...

伟大的大神,那天空了你帮我看看添加开关的问题嘛,你qq是多少?
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

都是前端的知识了
我的恩山、我的无线 The best wifi forum is right here.
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

有疑问请添加管理员QQ86788181|手机版|小黑屋|Archiver|恩山无线论坛(常州市恩山计算机开发有限公司版权所有) ( 苏ICP备05084872号 )

GMT+8, 2024-4-27 16:18

Powered by Discuz! X3.5

© 2001-2024 Discuz! Team.

| 江苏省互联网有害信息举报中心 举报信箱:js12377 | @jischina.com.cn 举报电话:025-88802724 本站不良内容举报信箱:68610888@qq.com 举报电话:0519-86695797

快速回复 返回顶部 返回列表