关于PPPoE协议

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/notbaron/article/details/80348993

PPPoE英语:Point-to-Point Protocol Over Ethernet),以太网上的点对点协议,是将点对点协议(PPP)封装在以太网(Ethernet)框架中的一种网络隧道协议。本质上,它是一个允许在以太网 广播域中的两个以太网接口间创建点对点隧道的协议。

PPPoE是一种用于将多个客户端连接到远程场点的规范。PPPoE协议在1999年发布在RFC2516中规范。

PPPoE包含两个阶段:发现阶段,会话阶段。

pppoe报头定义的结构体为pppoe_hdr,

位于文件include/uapi/linux/if_pppox.h,定义如下

struct pppoe_hdr {

#if defined(__LITTLE_ENDIAN_BITFIELD)

        __u8 type : 4;

        __u8 ver : 4;

#elif defined(__BIG_ENDIAN_BITFIELD)

        __u8 ver : 4;

        __u8 type : 4;

#else          

#error  "Please fix <asm/byteorder.h>"

#endif                                                   

        __u8 code;

        __be16 sid;    

        __be16 length;

        struct pppoe_tag tag[0];

} __packed;

报头结构体如下:


1.   PPPoE初始化

PPPoE初始化由方法pppoe_init完成,注册两个PPPoE协议处理程序,一个用于处理PPPoE发现数据包,另一个用于处理PPPoE会话数据包。

static int __init pppoe_init(void)

{

    ……

    err = register_pernet_device(&pppoe_net_ops);

    ……

        dev_add_pack(&pppoes_ptype);

        dev_add_pack(&pppoed_ptype);

        register_netdevice_notifier(&pppoe_notifier);

    ……

}

static struct packet_type pppoes_ptype __read_mostly = {

        .type   = cpu_to_be16(ETH_P_PPP_SES),

        .func   = pppoe_rcv,

};

static struct packet_type pppoed_ptype __read_mostly = {

        .type   = cpu_to_be16(ETH_P_PPP_DISC),

        .func   = pppoe_disc_rcv,

};

static struct pernet_operations pppoe_net_ops = {

        .init = pppoe_init_net,

        .exit = pppoe_exit_net,

        .id   = &pppoe_net_id,

        .size = sizeof(struct pppoe_net),

};

       其中pppoe_disc_rcv是发现数据包处理程序,pppoe_rcv是会话数据包处理程序。

PPPoE模块导出了一个procfs条目/proc/net/pppoe。

       register_netdevice_notifier(&pppoe_notifier)函数注册了一个通知链。

static struct notifier_block pppoe_notifier = {

        .notifier_call = pppoe_device_event,

};

2.   PPPoX套接字

PPPox套接字用结构pppox_sock表示,位于include/linux/if_pppox.h,实现了一个通用PPP封装套接字簇。除了PPPoE外,PPP第2层隧道协议L2TP也是用这种套接字。

struct pppox_sock {     

        /* struct sock must be the first member of pppox_sock */

        struct sock sk; 

        struct ppp_channel chan; 

        struct pppox_sock       *next;    /* for hash table */

        union {         

                struct pppoe_opt pppoe;  

                struct pptp_opt  pptp;   

        } proto;

        __be16                  num;

};

其中pppoe_opt包含一个名为pa的成员,是一个pppoe_addr结构实例,表示会话id,远程对等体的MAC地址以及使用的网络设备名称。


阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页