一、 PPPoE 整体实现框架
图1:整体框架PPPoE 程序首先PPPoE完成PPPoE的发现阶段(即相互通知MAC地址),接着这个程序负责发送/接收所有通过ppp网络接口(如ppp0)的数据包。
在会话阶段,PPPoE从网口和stdin接收数据,向stdout发送数据。(PPPD程序在启动PPPoE程序时,将PPPoE程序的stdin和stdout都重定向到PTY的主设备)
PPPD 程序
与PPPoE 程序配合起来完成拨号上网的协商与维护。
/dev/ppp
创建了ppp设备后,PPP过程的数据包经过协议栈的分类,会被传送到该接口的队列内。PPPD从该接口读取PPP过程的数据包,然后交给相应的协议栈处理。
对于响应的数据包同样写入该设备,设备内会将数据包交给协议栈然后转发出去。
socketPPPoE的会话与发现阶段数据包对应的以太网类型分别为0x8863和0x8864,内核中定义了这两种类型的socket。
PPP协议栈
主要负责PPP层的封装、压缩与解压。同时,它还对普通数据包和PPP过程的数据包进行了分流,将普通数据包提交给TCP/IP协议栈,而将PPP过程的数据包交给/dev/ppp设备队列中,等待PPPD去收取处理。
PTY设备
串行设备,PPP内核协议栈与PPPoE应用程序的中转站。因为PPP协议早多运行在串行链路上,所以在Linux内核中PPP协议栈与串行设备结合紧密。
伪终端的使用是成对出现的,分为 master 和 slaver 。写入主设备的信息,可以从从设备上读出;写入从设备的信息,可以从主设备读出。
二、 PPPoE的实现客户端
rp-pppoe
PPPoE 背景
传统的PPP连接是基于点到点的,而在以太网是muti-accesss,即在以太网中的任一节点可以访问其他节点。以太网中的Frame包含着目的节点的MAC地址以找到目的节点。 所以在转换PPP frame之前,两个通信节点必须事先知道对方的MAC地址。
PPPoE的两个阶段
DISCOVERY阶段:以太网中的节点交换通知MAC地址,并建立一个Session ID供后续的包交换使用。处理函数为discovery()
SESSION阶段:当节点之间知道了相互的MAC地址后,就进入了SESSION阶段。处理函数为session()
三、 PPP的实现