PPPoE协议.docx
《PPPoE协议.docx》由会员分享,可在线阅读,更多相关《PPPoE协议.docx(15页珍藏版)》请在冰点文库上搜索。
PPPoE协议
AMethodforTransmittingPPPOverEthernet(PPPoE)
在以太网上传输PPP的方法
RFC2516
目录
1.前言3
2.简介3
3.协议总述3
4.Payloads有效载荷4
5.Discovery阶段5
5.1.PPPoEActiveDiscoveryInitiation数据包(PADI)6
5.2.PPPoEActiveDiscoveryOffer数据包(PADO)6
5.3.PPPoEActiveDiscoveryRequest数据包(PADR)6
5.4.PPPoEActiveDiscoverySession-confirmation数据包(PADS)6
5.5.ThePPPoEActiveDiscoveryTerminate数据包(PADT)7
6.PPP会话阶段7
7.LCP方面的考虑7
8.其它方面的考虑8
9.安全方面的考虑8
10.参考文献8
附录A--TAG_TYPE和TAG_VALUE8
附录B--数据包的几个例子:
10
1.前言
点到点协议(PPP,参考文献[1])提供在点到点连路上传送多协议数据报的标准方法。
本文档描述在以太网上建立PPP会话以及封装PPP数据报的方法。
可行性
本说明书试图提供PPP所定义的工具,如链路控制协议(LinkControlProtocol,LCP),网络层控制协议(Network-layerControlProtocols,NCP),认证以及其它机制。
这些功能要求在通信双方之间存在点到点的关系,而不是在以太网和其他多访问环境中所出现的多点关系。
本规范可用于同一个以太网上的多个主机通过一个或多个跨接(桥接)调制解调器向多个目的主机建立PPP会话。
主要用于采用提桥接以太网拓扑结构的宽带远程访问技术中,由服务提供商维护PPP会话。
本文档描述的PPPoE是RedBackNetworks,RouterWare,UUNET及其它厂商所采用的在以太网上封装PPP的方法。
2.简介
现代接入技术需要面对有几个互相冲突的设计目标。
人们希望通过同一个家庭接入设备来连接到远程站点上的多个主机,同时(又希望在使用习惯上)提供与拨号上网(使用PPP)类似的访问控制和计费功能。
在很多接入技术中,把多个主机连接到家庭接入设备的最经济的方法就是通过以太网。
另外,还想尽量保持设备的低成本同时要求不改变或很少改变其配置。
以太网上的PPP(PPPoE)提供了通过简单桥接接入设备把一个网络的多个主机连接到远程接入集线器的功能。
使用该模型,每一个主机使用自己的PPP协议栈,呈现给用户的还是熟悉的用户接口。
访问控制、计费以及业务类型都能基于每一个用户,而不是基于站点。
为了提供以太网上的点到点连接,每一个PPP会话必须知道对端的以太网地址,并建立一个唯一的会话标识符。
PPPoE包含一个(以太网地址)发现协议来提供这个功能。
3.协议总述
PPPoE分为两个阶段,即Discovery(地址发现)阶段和PPP会话阶段。
当某个主机希望发起一个PPPoE会话时,它必须首先执行Discovery来确定对方的以太网MAC地址并建立起一个PPPoE会话标识符SESSION_ID。
虽然PPP定义的是端到端的对等关系,Discovery却是天生的一种客户端-服务器关系。
在Discovery的过程中,由主机(作为客户端)来发现接入集线器(AccessConcentrator,作为服务器)。
根据网络的拓扑结构,可能存在不止一个能和主机进行通信的接入集线器。
Discovery阶段允许主机发现所有的接入集线器并从中选择一个。
当Discovery阶段成功完成之后,主机和接入集线器两者都具备了用于在以太网上建立点到点连接所需的所有信息。
Discovery阶段保持无状态(stateless)直到建立起一个PPP会话。
一旦PPP会话建立,主机和访问集中器两者都必须为一个PPP虚拟接口分配资源。
4.Payloads有效载荷
这里定义了下面所示的数据包格式。
payload的内容将在Discovery和PPP的章节中描述。
以太网的帧格式如下所示:
1
0123456789012345
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|DESTINATION_ADDR|
|(6octets)|
||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|SOURCE_ADDR|
|(6octets)|
||
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|ETHER_TYPE(2octets)|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
~~
~payload~
~~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|CHECKSUM|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
DESTINATION_ADDR域是一个以太网单播目的地址或者以太网广播地址(0xffffffff)。
对于Discovery数据包来说,该域的值是在Descovery章节中定义的单播或者多播地址。
对于PPP会话流来说,该域必须是Descovery阶段已确定的通信对方的单播地址。
SOURCE_ADDR域必须包含源设备的以太网MAC地址。
ETHER_TYPE设置为0x8863(Discovery阶段)或者0x8864(PPP会话阶段)。
采用PPPoE时,以太网帧的payload如下所示:
123
01234567890123456789012345678901
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|VER|TYPE|CODE|SESSION_ID|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|LENGTH|payload~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
VER域为4bit,PPPoE规范的本版本必须设置为0x1。
TYPE域为4bit,PPPoE规范的本版本必须设置为0x1。
CODE域为8bit,其取值在后面的Discovery和PPP会话章节分别指定。
SESSION_ID域为16位,是一个网络字节序的无符号值。
其值在后面Discovery数据包中定义。
对一个给定的PPP会话来说该值是一个固定值,并且与以太网SOURCE_ADDR和DESTINATION_ADDR一起实际地定义了一个PPP会话。
值0xffff为将来的使用保留,不允许使用。
LENGTH域为16位。
该值(网络字节序)表明了PPPoE的payload长度。
不包括以太网头部和PPPoE头部的长度。
5.Discovery阶段
Discovery阶段由4个步骤组成。
完成之后通信双方都知道了PPPoESESSION_ID以及对方以太网地址,它们共同定义了唯一的PPPoE会话。
这些步骤包括:
✧主机广播一个Initiation(发起)数据包(以请求建立链路),
✧一个或多个接入集线器发送Offer(提供)数据包
✧主机发送单播SessionRequest(会话请求)数据包
✧选中的接入集线器发送Confirmation(确认)数据包
当主机接收到确认数据包后,它就可以进入PPP会话阶段。
接入集线器发送确认数据包后,它就可以进入到PPP会话阶段。
Discovery阶段所有的以太网帧的ETHER_TYPE域都设置为0x8863。
PPPoE的payload部分包含0个或多个TAG。
一个TAG是一个TLV(type-length-value)结构,定义如下:
123
01234567890123456789012345678901
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|TAG_TYPE|TAG_LENGTH|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|TAG_VALUE...~
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
TAG_TYPE域为16bit值(网络字节序),附录A列出了各种TAG_TYPE和TAG_VALUE。
TAG_LENGTH域为16bit,是无符号值(网络字节序),表明TAG_VALUE的字节数。
如果收到的discovery数据包中包含未知的TAG_TYPE,则必须忽略掉该TAG,除非本文档特别指出。
这样规定是为了在增加新的TAG时保持向后兼容。
如果增加强制使用的TAG,则版本号(version)将会提高。
附录B中有一些Discovery数据包的例子。
5.1.PPPoEActiveDiscoveryInitiation数据包(PADI)
主机发送DESTINATION_ADDR为广播地址的PADI数据包,CODE域设置为0x09,SESSION_ID域必须设置为0x0000。
PADI数据包包含:
✧TAG_TYPE为Service-Name的TAG。
它表示主机请求的服务(必须有,而且只能有一个)
✧任意数目的其它类型的TAG。
整个PADI数据包(包括PPPoE头部)不允许超过1484个字节,以留足空间让中继代理(向数据包中)增加类型为Relay-Session-Id的TAG。
5.2.PPPoEActiveDiscoveryOffer数据包(PADO)
如果接入集线器能够为收到的PADI请求提供服务,它将通过发送一个PADO数据包来做出应答。
DESTINATION_ADDR为发送PADI的主机的单播地址,CODE域为0x07,SESSION_ID域必须设置为0x0000。
PADO数据包必须包含:
✧TAG_TYPE为AC-Name的TAG(包含了访问集中器的名字)
✧与PADI中相同的TAG_TYPE为Service-Name的TAG
✧任意数目的类型为Service-Name的TAG表明接入集线器提供的其它服务。
如果接入集线器不能为PADI提供服务,则不允许用PADO作响应。
5.3.PPPoEActiveDiscoveryRequest数据包(PADR)
由于PADI是广播的,主机可能收到不止一个PADO,它将审查接收到的所有PADO并从中选择一个。
可以根据其中的AC-Name或PADO所提供的服务来作出选择。
然后主机向选中的访问集中器发送一个PADR数据包。
其中,DESTINATION_ADDR域设置为发送PADO的接入集线器的单播地址,CODE域设置为0x19,SESSION_ID必须设置为0x0000。
PADR必须包含:
✧包含且仅包含一个TAG_TYPE为Service-Name的TAG,表明主机请求的服务
✧任意数目其他类型的TAG。
5.4.PPPoEActiveDiscoverySession-confirmation数据包(PADS)
当接入集线器收到一个PADR数据包,它就准备开始一个PPP会话。
它为PPPoE会话创建一个唯一的SESSION_ID并用一个PADS数据包来给主机作出响应。
DESTINATION_ADDR域为发送PADR数据包的主机的单播以太网地址,CODE域设置为0x65,SESSION_ID必须设置为所创建好的PPPoE会话标识符。
PADS数据包包含:
✧且仅包含一个TAG_TYPE为Service-Name的TAG,表明接入集线器已经接受了该PPPoE会话的服务类型
✧任意数目的其他类型的TAG
如果接入集线器不喜欢PADR中的Service-Name,那么它必须用一个带有类型为Service-Name-Error的TAG(以及任意数目的其它TAG类型)的PADS来作出应答。
这种情况下,SESSION_ID必须设置为0x0000。
5.5.ThePPPoEActiveDiscoveryTerminate数据包(PADT)
这种数据包可以在会话建立以后的任意时刻发送,表明PPPoE会话已经终止。
它可以由主机或接入集线器发送,DESTINATION_ADDR域为单播以太网地址,CODE域设置为0xa7,SESSION_ID设置为将要终止的会话的SESSION_ID,这种数据包不需要任何TAG。
当收到PADT以后,就不允许再使用该会话发送PPP数据流了。
在发送或接收到PADT后,即使是常规的PPP结束数据包也不允许发送。
PPP通信双方应该使用PPP协议自身来结束PPPoE会话,但在无法使用PPP时可以使用PADT。
6.PPP会话阶段
一旦PPPoE会话开始,PPP数据就像其它PPP封装一样发送。
所有的以太网数据包都是单播的。
ETHER_TYPE域设置为0x8864。
PPPoE的CODE必须设置为0x00。
PPPoE会话的SESSION_ID不允许发生改变,必须是Discovery阶段所指定的值。
PPPoE的payload包含一个PPP帧,帧始于PPPProtocol-ID。
附录B中给出了数据包的一个实例。
7.LCP方面的考虑
推荐使用MagicNumberLCP配置选项,不推荐使用协议域压缩(ProtocolFieldCompression,PFC)选项。
不允许协议实现体请求使用下面的任何一个配置选项,对此必须作出拒绝:
✧FieldCheckSequence(FCS)Alternatives,
✧Address-and-Control-Field-Compression(ACFC),
✧Asynchronous-Control-Character-Map(ACCM)
协商后(PPPoE)的最大接收单元(MRU)不允许超过1492。
因为以太网的最大净载为1500字节,而PPPoE头部为6个字节,PPPProtocol-ID为2个字节,所以PPP的MTU不允许超过1492。
建议接入集线器不时地向主机发送回声请求(Echo-Request)数据包,以确定会话的状态。
否则如果主机在没有发送结束请求(Terminate-Request)数据包的情况下终止会话,则接入集线器将无法得知该会话已经“死去”。
当LCP结束的时候,主机和接入集线器必须停止使用该PPPoE会话。
如果主机希望开始另一个PPP会话,则它必须重新进入PPPoEDiscoverey阶段。
8.其它方面的考虑
如果主机在一段指定时间内没有收到PADO数据包,它应该重发其PADI数据包并把等待的间隔加倍。
按所期望的次数重复这个动作。
主机在等待接收PADS数据包时,应该采用类似的定时机制,只是主机重新发送的是PADR数据包。
在重发指定次数后(还没有收到PADO),主机应该重新发送PADI。
本文档中的ETHER_TYPE(0x8863,0x8864)已经被IEEE指定专用于以太网上的PPP(PPPoE),使用这两个值和PPPoEVER(版本)域将唯一标识本协议。
本文档始终使用UTF-8(参考文献[5])而不是ASCII。
UTF-8支持所有ASCII字符集同时允许国际字符集。
参见参考文献[5]。
9.安全方面的考虑
为了防止拒绝服务攻击(DenialofService,简称DOS),接入集线器可以使用类型为AC-Cookie的TAG。
接入集线器应该能够根据PADR的SOURCE_ADDR来重新产生具有唯一性的TAG_VALUE。
使用这种方法,接入集线器可以确保PADI的SOURCE_ADDR确实是可到达的,并对该地址的并行会话数进行限制。
使用什么样的算法并没有指定,留给实现细节自己选择。
对主机MAC地址使用HMAC(参考文献[3])就是一个例子,(在进行HMAC密码散列时)使用的是仅有接入集线器知道的密码。
虽然AC-Cookie对防止某些DOS有用,但它不能防止所有的DOS攻击,接入集线器可以使用其它的方法来保护。
很多接入集线器不希望提供信息表明为未认证实体提供什么服务。
在这种情况下,接入集线器应该使用下面两种策略之一:
它应该根据请求中的Service-Name标签不拒绝该请求,并返回收到的TAG_VALUE;或者应该仅接受带有TAG_LENGTH为0(表明任意服务)的Service-Name标签的请求。
推荐使用前一种方案。
10.参考文献
[1]Simpson,W.,Editor,“点到点协议(PPP)”,STD51,RFC1661,July1994
[2]Bradner,S.,“RFC中表明条件级别的关键词”,BCP14,RFC2119,March1997.
[3]Krawczyk,H.,Bellare,M.andR.Canetti,“HMAC:
消息认证的密钥散列”,RFC2104,February1998.
[4]Reynolds,J.andJ.Postel,“指定值”,STD2,RFC1700,October1994.参见:
http:
//www.iana.org/numbers.html
[5]Yergeau,F.,“UTF-8,ISO10646的一种转换”,RFC2279,January1998.
附录A--TAG_TYPE和TAG_VALUE
0x0000End-Of-List
该TAG表明表中没有其它TAG了。
该TAG的TAG_LENGTH必须总是0。
不强制使用该标签,存在是为了向后兼容。
0x0101Service-Name
该TAG表明后面紧跟的是服务的名称。
TAG_VALUE是不以NULL结束的UTF-8字符串。
当TAG_LENGTH为0时,该TAG用于表明接受任何服务。
使用Service-Name标签的例子是表明ISP(Internet服务提供商)或者一类服务或者服务的质量。
0x0102AC-Name
该TAG表明后面紧跟的字符串唯一地表示了某个特定的接入集线器。
它可以是商标、型号以及序列号等信息的集合,或者该接入集线器MAC地址的一个简单的UTF-8表示。
它不以NULL来结束。
0x0103Host-Uniq
该TAG由主机用于把接入集线器的响应(PADO或者PADS)与主机的某个唯一特定的请求联系起来。
TAG_VALUE是主机选择的长度和值为任意的二进制数据。
它不能由接入集线器解释。
主机可以在PADI或者PADR中包含一个Host-Uniq标签。
如果接入集线器收到了该标签,它必须在对应的PADO或者PADS中不加改变的包含该标签。
0x0104AC-Cookie
该TAG由接入集线器用于防止拒绝服务攻击(见“安全方面的考虑”)。
接入集线器可以在PADO数据包中包含该TAG。
如果主机收到了该标签,它必须在接下来的PADR中不加改变的包含该标签。
TAG_VALUE是长度和值任意的二进制数据,不能由主机解释。
0x0105Vendor-Specific
该TAG用来传送厂商自定义的信息。
TAG_VALUE的头4个字节包含了厂商的识别码,其余字节尚未定义。
厂商识别码的高字节为0,低3个字节为网络字节序的厂商的SMI网络管理专用企业码,如“定义值RFC”(参考文献[4])中定义的那样。
不推荐使用该TAG。
为了确保互操作性,实现可以悄悄的忽略Vendor-SpecificTAG。
0x0110Relay-Session-Id
该TAG可由中间代理加入到Discovery数据包中。
TAG_VALUE对主机和访问集中器都是透明的(paque)。
如果主机或接入集线器收到该TAG,则它们必须在所有的Discovery数据包中包含该TAG以作为响应。
所有的PADI数据包必须保证足够空间来加入TAG_VALUE长度为12字节的Relay-Session-Id标签。
如果Discovery数据包中已经包含一个Relay-Session-Id标签,则不允许再加入该标签。
这种情况下,中间代理应该使用该现有的Relay-Session-Id标签。
如果它不能使用现有的标签,或者没有足够空间来增加一个Relay-Session-Id标签,那么它应该向发送者返回一个Generic-Error标签。
0x0201Service-Name-Error
该TAG(典型的有一个长度为零的数据部分)表明了由于某种原因,不能处理所请求的Service-Name。
如果有数据部分,并且数据部分的头一个字节非0,那么它必须是一个可打印的UTF-8字符串,解释请求被拒绝的原因。
该字符串可以不以NULL结束。
0x0202AC-System-Error
该TAG表明了接入集线器在处理主机请求时出现了某个错误。
(例如没有足够资源来创建一个虚拟电路。
PADS数据包中可以包含该标签。
如果有数据部分,并且数据的第一个字节不为0,那么它必须是一个可打印的UTF-8字符串,该字符串解释了错误的性质。
该字符串可以不以NULL结束。
0x0203Generic-Error
该TAG表明发生了一个错误。
当发生一个不可恢复的错误并且没有其它合适的TAG时,它可被加到PADO,PADR或PADS数据包中。
如果出现数据部分,那么数据必须是一个UTF-8字符串,解释错误的性质。
该字符串不允许以NULL结束。
附录B--数据包的几个例子:
PADI数据包:
123
01234567890123456789012345678901
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0xffffffff|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|0xffff|Host_mac_addr|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|Host_mac_addr(cont)|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
|ETHER_TYPE=0x8863|v=1|t=1|CODE=0x09|
+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+