转:http://blog.csdn.net/yangzheng_yz/article/details/11526671

PPP (Point-to-Point)提供了一种标准的方法在点对点的连接上传输多种协议数据包,它最常见的用途可能是传统的拨号上网了(据说现在的宽带接入 也有采用PPPOE方式的)。在Linux Mobile Phone上,网络应用程序使用PPP作为与GSM模组之间的通信协议,最近遇到了一点关于PPP的麻烦,所以花了点时间去研究它。

PPP 协议肯定不是最复杂的网络协议,不过pppd、chat、tty、socket、ccp、chap、pap、eap、ecp、ipcp和很多其它概念搅在 一起之后,谁都会被搞得晕头转向。我关心的其实是PPP协议中各个实体之间的协作关系,而不是协议的状态转换或者服务的配置,由于没有找到这方面的资料, 只好去读RFC,内核、pppd和一些网络工具的代码。

PPP协议提供两个实体之间的数据链路连接的建立、维持和释放,负责流量和差错控制等等功能,所以它应该是属于数据链路层协议的。

PPP 协议之下是以太网和串口等物理层,之上是IP协议等网络层。这里,对于下层,我们只讨论串口的情况,对于上层,我们只讨论TCP/IP的情况。发送时, TCP/IP数据包经过PPP打包之后经过串口发送。接收时,从串口上来的数据经PPP解包之后上报给TCP/IP协议层。

网络协议是分层实现的,上层一般只需要知道其直接下层,只有在极少数据情况才使用间接下层的接口。比如,彩信、浏览器和邮件等应用程序使用socket接口编程,它们只需要知道TCP/IP协议,而无需要知道PPP协议的存在。这种分层设计简化了协议的实现和应用程序的开发。

问题来了:PPP 协议不只是提供了简单的数据链路层功能,它还提供了诸如鉴权(如PAP/CHAP),数据压缩/解压(如CCP)和数据加密/解密(如ECP)等扩展功 能。应用程序要求使用透明化,不关心这些扩展功能的存在,而反过来,PPP协议处理模块本身又无法处理这些策略性的东西,因为它不知道用户名/密码,不知 道是否要进行压缩,不知道是否要进行加密。

怎么办?如何在对应用程序透明的情况下使用扩展功能呢?上帝说,这个问题必须解决!于是pppd就出现了。pppd是一个后台服务进程(daemon),是一个用户空间的进程,所以把策略性的内容从内核的PPP协议处理模块移到pppd中是很自然的事了。pppd实现了所有鉴权、压缩/解压和加密/解密等扩展功能的控制协议。

pppd只是一个普通的用户进程,它如何扩展PPP协议呢?这就是pppd与内核中的PPP协议处理模块之间约定了,它们之间采用了最传统的内核空间与用户空间之间通信方式:设备文件。

设备文件名是/dev/ppp。 通过read系统调用,pppd可以读取PPP协议处理模块的数据包,当然,PPP协议处理模块只会把应该由pppd处理的数据包发给pppd。通过 write系统调用,pppd可以把要发送的数据包传递给PPP协议处理模块。通过ioctrl系统调用,pppd可以设置PPP协议的参数,可以建立/ 关闭连接。

在pppd 里,每种协议实现都在独立的C文件中,它们通常要实现protent接口,该接口主要用于处理数据包,和fsm_callbacks接口,该接口主要用于 状态机的状态切换。数据包的接收是由main.c: get_input统一处理的,然后根据协议类型分发到具体的协议实现上。而数据包的发送则是协议实现者根据需要调用output函数完成的。

chat是pppd所带一个辅助工具。呵,它和xchat不是一个类型的,xchat用来与人聊天,而chat用来与GSM模组建立会话。它的实现比较简单,它向串口发送AT命令,建立与GSM模组的会话,以便让PPP协议可以在串口上传输数据包。

应用程序通过socket 接口发送TCP/IP数据包,这些TCP/IP数据包如何流经PPP协议处理模块,然后通过串口发送出去呢?pppd在make_ppp_unit函数中 调用ioctrl(PPPIOCNEWUNIT)创建一个网络接口(如ppp0),内核中的PPP协议模块在处理PPPIOCNEWUNIT时,调用 register_netdev向内核注册ppp的网络接口,该网络接口的传输函数指向ppp_start_xmit。

当应用程序发送数据时,内核根据IP 地址和路由表,找到ppp网络接口,然后调用ppp_start_xmit函数,此时控制就转移到PPP协议处理模块了。ppp_start_xmit调 用函数ppp_xmit_process去发送队列中的所有数据包,ppp_xmit_process又调用ppp_send_frame去发送单个数据 包,ppp_send_frame根据设置,调用压缩等扩展处理之后,又经ppp_push调用pch->chan->ops-> start_xmit发送数据包。

pch ->chan->ops->start_xmit是什么?它就是具体的传输方式了,比如说对于串口发送方式,则是 ppp_async.c: ppp_asynctty_open中注册的ppp_async_send函数,ppp_async_send经ppp_async_push函数调用 tty->driver->write把数据发送串口。

用户数据发送过程如下图所示:

pppd的控制协议数据发送过程如下图所示:

反过来,接收数据的情形又是如何的?ppp_async.c在初始化时(ppp_async_init),调用tty_register_ldisc向tty注册了行规程处理接口,也就是一组回调函数,当串口tty收到数据时,它就会回调ppp_ldisc的ppp_asynctty_receive函数接收数据。ppp_asynctty_receive调用ppp_async_input把数据buffer转换成sk_buff,并放入接收队列ap->rqueue中。

ppp_async另外有一个tasklet(ppp_async_process)专门处理接收队列ap->rqueue中的数据包,ppp_async_process一直挂在接收队列ap->rqueue上,一旦被唤醒,它就调用ppp_input函数让PPP协议处理模块处理该数据包。

在ppp_input函数中,数据被分成两路,一路是控制协议数据包,放入pch->file.rqb队列,交给pppd处理。另外一路是用户数据包,经ppp_do_recv/ppp_receive_frame进行PPP处理之后,再由netif_rx提交给上层协议处理,最后经socket传递到应用程序。

数据接收过程如下图所示:

PPP协议的流程基本清楚了,不过还有不少细节有待进一步研究。

Linux ppp 数据收发流程的更多相关文章

  1. linux 网络数据收发网络流量监控

    网卡流量 1.iftop命令 iftop可以用来监控网卡的实时流量(可以指定网段).反向解析IP.显示端口信息.TCP/IP连接等官网:http://www.ex-parrot.com/~pdw/if ...

  2. Linux网络(网络模型和收发流程)

    网络模型 为了解决网络互联中异构设备的兼容性问题,并解耦复杂的网络包处理流程,国际标准化组织制定的开放式系统互联通信参考模型(Open System Interconnection Reference ...

  3. Linux input系统数据上报流程【转】

    转自:https://segmentfault.com/a/1190000017255939 作为鸡生蛋系列文章,这里主要关注Linux input系统,主要为触摸事件上报流程. 读该文章最好有对li ...

  4. Linux系统捕获数据包流程

    Linux系统捕获数据包流程 为了提高数据包的捕获效率,瓶颈问题是一个需要非常关注的焦点.减少在捕获数据包过程中的瓶颈,就能够提高数据包捕获的整体性能.下面本文将以Linux操作系统为平台,分析捕获数 ...

  5. Linux网络底层收发探究【转】

    转自:https://blog.csdn.net/davion_zhang/article/details/51536807 本文为博主原创文章,未经博主允许不得转载. https://blog.cs ...

  6. Linux操作系统备份之三:通过二进制拷贝(dd)方式实现Linux操作系统数据的备份

    前面有两篇文章,<Linux操作系统备份之一:使用LVM快照实现Linux操作系统数据的在线备份>和<Linux操作系统备份之二:通过tar拷贝分区实现Linux操作数据的在线备份& ...

  7. Linux内核数据包的发送传输

    本文主要讲解了Linux内核数据包的传输流程,使用的内核的版本是2.6.32.27 为了方便理解,本文采用整体流程图加伪代码的方式从内核高层面上梳理了二层数据包发送传输的流程,希望可以对大家有所帮助. ...

  8. Linux操作系统-CentOS6启动流程和服务管理

    Linux操作系统-CentOS6启动流程和服务管理 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.Linux组成 1>.Linux: kernel+rootfs ker ...

  9. Linux系统文件与启动流程

    Linux系统文件与启动流程 /etc初始化系统重要文件 /etc/sysconfig/network-scripts/ifcfg-eth0:网卡配置文件 /etc/resolv.conf:Linux ...

随机推荐

  1. swift 第九课 用tableview 做一个下拉菜单Menu

    写到这里的时候,自己这个项目已经完成了一半左右,项目进度自己还是挺满意.今天又有一个新的布局,要实现个下拉菜单,刚开始写的时候,觉得会很容易,后来发现也是小错不断, 我想自己限制的自己属于写博客的初期 ...

  2. Chrome安装json格式化工具jsonView

    1.下载jsonView 有条件的童鞋可以去谷歌商店下载安装https://chrome.google.com/webstore/detail/pmajcnnfhjcebiafkonednglookd ...

  3. BFS算法模板(python实现)

    BFS算法整理(python实现) 广度优先算法(Breadth-First-Search),简称BFS,是一种图形搜索演算算法. 1. 算法的应用场景 2. 算法的模板 2.1 针对树的BFS模板 ...

  4. 最新 央视网java校招面经 (含整理过的面试题大全)

    从6月到10月,经过4个月努力和坚持,自己有幸拿到了网易雷火.京东.去哪儿.央视网等10家互联网公司的校招Offer,因为某些自身原因最终选择了央视网.6.7月主要是做系统复习.项目复盘.LeetCo ...

  5. js的new Date兼容iOS和Android

    在写一个移动端的报名活动页面时,其中一个逻辑是:过了报名日期,“立即报名”按钮置灰,不允许报名:具体逻辑如下,在真机上测试的时候,Android端可以把按钮失效,iOS则是无法把按钮失效.后台返回的时 ...

  6. apue-ubuntu环境搭建

    目录 apue环境搭建 title: apue环境搭建 date: 2019/11/19 19:25:18 toc: true --- apue环境搭建 下载编译 wget http://www.ap ...

  7. ActiveMQ单机部署及简单应用

    系统版本:Centos 7 前言 MQ是消息中间件,是一种在分布式系统中应用程序借以传递消息的媒介,常用的有ActiveMQ,RabbitMQ,kafka.ActiveMQ是Apache下的开源项目, ...

  8. Python+requests 发送简单请求--》获取响应状态--》获取请求响应数据

    Python+requests 发送简单请求-->获取响应状态-->获取请求响应数据 1.环境:安装了Python和vscode编译器(Python自带的编译器也ok).fiddler抓包 ...

  9. 使用mybatis出现异常:invalid comparison: java.time.LocalDateTime and java.lang.String

    整了半天终于找到问题所在:在mapper文件中,对该参数进行了和字符串的对比,如下: <if test="startTime != null and startTime != '' a ...

  10. 新拉的项目在idea中启动时报如下错误:org.apache.catalina.core.ContainerBase.addChildInternal ContainerBase.addChild: start:

    今天真的是很苦恼,之前启动项目没有任何问题,今天突然启动时给我报了如下一个错误. 详细报错信息: org.apache.catalina.core.ContainerBase.addChildInte ...