PPPOE协议简介(部分)

PPPOE(PPP over Ethernet)
pppoe在标准PPP报文的前面加上以太网的报头。

1.PPPOE帧格式
DESTINATION_ADDR  SOURCE_ADDR    ETHER_TYPE  PAYLOAD  CHECKSUM
  6                   6        2                    1

PAYLOAD:
VER     TYPE    CODE    SESSION_ID     LENGTH     PLAYLOAD1
0001    0001    8BIT      2               2        

PLAYLOAD1:
TAG_TYPE   TAG_LENGTH   TAG_VALUE   .....


ETHER_TYPE:
0X8863  Discovery Stage
0x8864  PPP Session Stage
CODE:
0x00    PPP Session Stage
0x09    PPPOE Active Discovery Initiation(PADI) packet
0x07  PPPOE Active Discovery Offer(PADO) packet
0x19    PPPOE Active Discovery Request(PADR) packet
0x65    PPPOE Active Discovery Session-confirmation(PADS) PACKET
0xa7    PPPOE Active Discovery Terminate(PADT) packet
TAG_TYPES:
0x0000 End_Of_List
0x0101 Service-Name
0x0102 AC-Name
0x0103 Host_Uniq
0x0104 AC-Cookie
0x0105 Vendor-Specific
0x0110 Relau-Session-Id
0x0201 Service-Name-Error
0x0202 AC-System-Error
0x0203 Generic-Error

 

PPPoE协议工作原理
两个阶段:发现阶段,会话阶段。

发现阶段分为4个步骤,主要目的是建立唯一的PPPoE的SessionID.
 1.客户端广播发分组(PADI):目的:客户端寻找服务器。实现:客户端发送CODE:0x09,SESSION-ID=0x0000,标签类型字段值为0x0101,地址0xffffffffffff;
 2.服务器收(PADI)发(PAD0): 目的:服务器反馈客户端。实现:服务端发送CODE:0x07,SESSION-ID=0x0000,标签类型字段值为0x0102(以及一个或多个服务器),地址客户端;
 3.客户端选服务器发(PADR):目的;多服务器优先选择。实现:客户端发送CODE:0x19,SESSION-ID=0x0000,客户端未收到PAD0,就重发PAD1,并加长等待时间。地址客户端;
 4.服务端发会话确认(PADS): 目的:准备开始PPP会话。 实现:服务端发送CODE:0x65,SESSION-ID=唯一.客户端收到PADS确认后吗,开始会话阶段。

  用户终端   ADSL局端
发 ---------PADI-------->
现 <--------PAD0---------
阶 ---------PADR-------->
段 <--------PADS---------
  <------PPP Data------>   会话阶段
  <--------PADT-------->  会话释放
会话阶段: 
  PPDT可以在会话建立后任何时刻发送,终止PPPoE会话。CODE:0xa7,SESSION-ID.
 
 
代码分析:
typedef struct PPPoEConnectionStruct {
    int discoveryState;        /* Where we are in discovery */
    int discoverySocket;       /* Raw socket for discovery frames */
    int sessionSocket;        /* Raw socket for session frames */
    unsigned char myEth[ETH_ALEN];   /* My MAC address */
    unsigned char peerEth[ETH_ALEN];  /* Peer's MAC address */
    UINT16_t session;         /* Session ID */
    char *ifName;           /* Interface name */
    char *serviceName;        /* Desired service name, if any */
    char *acName;           /* Desired AC name, if any */
    int synchronous;         /* Use synchronous PPP */
    int useHostUniq;         /* Use Host-Uniq tag */
    int printACNames;         /* Just print AC names */
    int skipDiscovery;        /* Skip discovery */
    int noDiscoverySocket;      /* Don't even open discovery socket */
    int killSession;         /* Kill session and exit */
    FILE *debugFile;         /* Debug file for dumping packets */
    int numPADOs;           /* Number of PADO packets received */
    PPPoETag cookie;         /* We have to send this if we get it */
    PPPoETag relayId;         /* Ditto */
    int PADSHadError;              /* If PADS had an error tag */
    int discoveryTimeout;          /* Timeout for discovery packets */
} PPPoEConnection;

你可能感兴趣的:(嵌入式开发)