Linux PPP实现源码分析-1

前言:

PPP(Point to Point Protocol)协议是一种广泛使用的数据链路层协议,在国内广泛使用的宽带拨号协议PPPoE其基础就是PPP协议,此外和PPP相关的协议PPTP,L2TP也常应用于VPN虚拟专用网络。随着智能手机系统Android的兴起,PPP协议还被应用于GPRS拨号,3G/4G数据通路的建立,在嵌入式通信设备及智能手机中有着广泛的应用基础。本文主要分析Linux中PPP协议实现的关键代码和基本数据收发流程,对PPP协议的详细介绍请自行参考RFC和相关协议资料。

模块组成:


上图为PPP模块组成示意图,包括:

PPPD:PPP用户态应用程序。

PPP驱动:PPP在内核中的驱动部分,kernel源码在/drivers/net/下的ppp_generic.c, slhc.c。

PPP线路规程*:PPP TTY线路规程,kernel源码在/drivers/net/下的ppp_async.c, ppp_synctty.c,本文只考虑异步PPP。

TTY核心:TTY驱动,线路规程的通用框架层。

TTY驱动:串口TTY驱动,和具体硬件相关,本文不讨论。

说明:本文引用的pppd源码来自于android 2.3源码包,kernel源码版本为linux-2.6.18。

Linux中PPP实现主要分成两大部分:PPPD和PPPK。PPPD是用户态应用程序,负责PPP协议的具体配置,如MTU、拨号模式、认证方式、认证所需用户名/密码等。 PPPK指的是PPP内核部分,包括上图中的PPP驱动和PPP线路规程。PPPD通过PPP驱动提供的设备文件接口/dev/ppp来对PPPK进行管理控制,将用户需要的配置策略通过PPPK进行有效地实现,并且PPPD还会负责PPP协议从LCP到PAP/CHAP认证再到IPCP三个阶段协议建立和状态机的维护。因此,从Linux的设计思想来看,PPPD是策略而PPPK是机制;从数据收发流程看,所有控制帧(LCP,PAP/CHAP/EAP,IPCP/IPXCP等)都通过PPPD进行收发协商,而链路建立成功后的数据报文直接通过PPPK进行转发,如果把Linux当做通信平台,PPPD就是Control Plane而PPPK是DataPlane。

在Linux中PPPD和PPPK联系非常紧密,虽然理论上也可以有其他的应用层程序调用PPPK提供的接口来实现PPP协议栈,但目前使用最广泛的还是PPPD。PPPD的源码比较复杂,支持众多类UNIX平台,里面包含TTY驱动,字符驱动,以太网驱动这三类主要驱动,以及混杂了TTY,PTY,Ethernet等各类接口,导致代码量大且难于理解,下文我们就抽丝剥茧将PPPD中的主干代码剥离出来,遇到某些重要的系统调用,我会详细分析其在Linux内核中的具体实现。

源码分析:

PPPD的主函数main:

第一阶段:

pppd/main.c -> main():

……

//PPPD中的状态机,目前是初始化阶段

    /*

     * Initialize magic number generator now so that protocols may

     * use magic numbers in initialization.

     */

    magic_init();

 

    /*

     * Initialize each protocol.

     */

NULL//protocols[]是全局变量的协议数组

//初始化协议数组中所有协议

 

    /*

     * Initialize the default channel.

     */

    tty_init()//channel初始化,默认就是全局的tty_channel,里面包括很多TTY函数指针   

//解析/etc/ppp/options中的参数

//解析PPPD命令行参数

/* can no longer change device name */

 

    /*

     * Work out the device name, if it hasn't already been specified,

     * and parse the tty's options file.

     */

//实际上是调用tty_process_extra_options解析TTY 参数

//检测/dev/ppp设备文件是否有效

no_ppp_msg);

    }

    /*

     * Check that the options given are valid and consistent.

     */

    check_options()//检查选项参数

//检测系统参数,比如内核是否支持Multilink等

    auth_check_options()//检查认证相关的参数

#ifdef HAVE_MULTILINK

    mp_check_options();

#endif

NULL

NULL)

//检查每个控制协议的参数配置 

//实际上是调用tty_check_options检测TTY参数

 

……

    /*

     * Detach ourselves from the terminal, if required,

     * and identify who is running us.

     */

updetach

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值