修改FreeBSD-5-stable的ppp(8)和pppoed(8)

yayj 发表于 2005-12-16 16:32:09

ppp(8)和pppoed(8)都是FreeBSD系统自己的用户级ppp处理程序,配合使用这两个程序可以使FreeBSD成为一个pppoe服务器。pppoed(8)作为daemon进程一直运行,当收到与之对应的PADI后,pppoed(8)会fork出ppp(8)来处理这个连接,每个ppp(8)进程只处理与这对应的ppp接口。

需求:
1. ppp(8)使用tunN作为ppp接口名,其中包括有一个adsl的接口,所以adsl接口的名称不固定,这对做NAT的pf(4)配置造成了困难。要求固定adsl接口的名称,并使其它的pppoe不能使用该接口名称。
2. ppp(8)不提供限制用户登录次数的功能,要求提供该功能。
3. ppp(8)能统计它对应接口的流量,但不提供统计用户流量的功能,要求提供该功能。

完成情况:
1. ppp(8)默认从tun0开始一直重试到打开tunN设备为止,而它的-unit N选项表示只使用tunN接口,所以只要修改-unit选项的意义即可。而pppoed(8)在调用ppp(8)时不会使用-unit选项,所以要为它加上这个功能。
pppoe.c.diffs如下:
--- pppoed.c.orig Sat Nov 15 23:26:34 2003
+++ pppoed.c Fri Dec 16 16:18:20 2005
@@ -61,7 +61,7 @@
#include


-#define DEFAULT_EXEC_PREFIX "exec /usr/sbin/ppp -direct "
+#define DEFAULT_EXEC_PREFIX "exec /usr/sbin/fixedppp -direct -unit "
#define HISMACADDR "HISMACADDR"
#define SESSION_ID "SESSION_ID"

@@ -503,7 +503,7 @@
struct ngm_connect ngc;
struct sigaction act;
int ch, cs, ds, ret, optF, optd, optn, sz, f;
- const char *pidfile;
+ const char *pidfile, *unit;

prog = strrchr(argv[0], '/');
prog = prog ? prog + 1 : argv[0];
@@ -512,14 +512,19 @@
label = NULL;
acname = NULL;
provider = "";
+ unit = "0 ";
optF = optd = optn = 0;

- while ((ch = getopt(argc, argv, "FP:a:de:l:n:p:")) != -1) {
+ while ((ch = getopt(argc, argv, "Fu:P:a:de:l:n:p:")) != -1) {
switch (ch) {
case 'F':
optF = 1;
break;

+ case 'u':
+ unit = optarg;
+ break;
+
case 'P':
pidfile = optarg;
break;
@@ -568,14 +573,16 @@
" must be given\n", prog);
return usage(prog);
}
- exec = (char *)alloca(sizeof DEFAULT_EXEC_PREFIX + strlen(label));
+ exec = (char *)alloca(sizeof DEFAULT_EXEC_PREFIX + strlen(label) + strlen(unit) + 1);
if (exec == NULL) {
fprintf(stderr, "%s: Cannot allocate %d bytes\n", prog,
(int)(sizeof DEFAULT_EXEC_PREFIX) + strlen(label));
return EX_OSERR;
}
strcpy(exec, DEFAULT_EXEC_PREFIX);
- strcpy(exec + sizeof DEFAULT_EXEC_PREFIX - 1, label);
+ strcat(exec, unit);
+ strcat(exec, " ");
+ strcat(exec, label);
}

if (acname == NULL) {
这个很简单,ppp(8)的更简单,把bundle.c的2019行中改为maxunit = -1;即可。

2. 这个需要实现每个ppp进程间的通信与同步。我现在的做法是以用户名作为文件名,把进程的pid存入该文件,并用文件锁来实现各个ppp进程间的同步。新 的ppp进程验证前先检查这个文件,如果文件不存在或者文件中的pid对应的进程不存在则表示用户没有登录,否则用户已经在线了。修改pap.c中的 pap_Input函数和chap.c中的chap_Input函数实现pid的存入操作,修改main.c中的AbortProgram函数实现清理工 作。

3. 还没写好。

体会:
1. alloca函数很好用。
2. 要看懂一个程序,必须先看懂它的数据结构。
3. 这次看程序全部使用cscope+vim完成,很好用,还有很多功能示发现。



收藏: QQ书签 del.icio.us 订阅: Google 抓虾

最新评论

发表评论

* 昵称

已经注册过? 请登录

新用户请先注册 以便能显示头像及追踪评论回复

Email
网址
* 评论
表情
 
 

分类小组论坛
杂谈, 娱乐、八卦, 文学、艺术, 体育, 旅游、同城, 象牙塔, 情感, 时尚、生活, 星座, 科技

请注意遵守中华人民共和国法律法规, 如威胁到本站生存, 将依法向有关部门报告, 同时本站的相关记录可能成为对您不利的证据.

相关法律法规
全国人大常委会关于维护互联网安全的决定
中华人民共和国计算机信息系统安全保护条例
中华人民共和国计算机信息网络国际联网管理暂行规定
计算机信息网络国际联网安全保护管理办法
计算机信息系统国际联网保密管理规定