PPP协议之下是以太网和串口等物理层,之上是IP协议等网络层。这里,对于下层,我们只讨论串口的情况,对于上层,我们只讨论TCP/IP的情况。发送时,TCP/IP数据包经过PPP打包之后经过串口发送。接收时,从串口上来的数据经PPP解包之后上报给TCP/IP协议层。pppd是一个后台服务进程(daemon),是一个用户空间的进程,所以把策略性的内容从内核的PPP协议处理模块移到pppd中是很自然的事了。pppd实现了所有鉴权、压缩/解压和加密/解密等扩展功能的控制协议。在移动终端向监控中心发送定位信息的过程中,移动终端上的GPRS通信程序通过socket接口发送TCP/IP数据包,内核根据IP地址和路由表,找到PPP网络接口,然后调用函数ppp_start_xmit(),此时控制权就转移到了PPP协议模块。函数ppp_start_xmit()调用函数ppp_xmit_process()去发送队列中的所有数据包,而函数ppp_xmit_process()会进一步调用函数ppp_send_frame()去发送单个数据包。函数ppp_send_frame()根据前面pppd对PPP协议模块的设置调用压缩等扩展功能之后,又经函数ppp_push()调用函数pch->chan->ops->start_xmit()发送数据包。函数pch->chan->ops->start_xmit()是具体的传输方式,对于串口发送方式,:ppp_asynctty_open中注册的函数ppp_async_send(),函数ppp_async_send()经函数ppp_async_push()调用函数tty->driver->write()(定义在低层驱动程序中)把数据发送到串口2(GPRS通信模块接在串口2上)。 (ppp_async_init),调用函数tty_register_ldisc()向tty注册了行规程N_PPP的处理接口,也就是一组回调函数。在移动终端接收监控中心指令的过程中,当GPRS通信模块收到数据时,就会回调N_PPP行规程中的函数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->,交给pppd处理。另外一路是用户数据包,经函数ppp_do_recv()、ppp_receive_frame()进行PPP协议相关的处理后,if_rx()提交给上层的TCP/IP协议模块进行处理,最后经socket接口传递给应用层的GPRS通信程序。=====================1)ppp设备是指在点对点的物理链路之间使用PPP帧进行分组交换的内核网络接口设备,由于Linux内核将串行设备作为终端设备来驱动,,PPP规程分为异步规程(N_PPP)和同步规程(N_SYNC_PPP)两种,)在PPP驱动程序中,每一tty终端设备对应于一条PPP传输通道(chanell),每一ppp网络设备对应于一个PPP接口单元(unit).从终端设备上接收到的数据流通过PPP传输通道解码后转换成PPP帧传递到PPP网络接口单元,,当PPP设备发射数据帧时,发射帧通过PPP接口单元转换成PPP帧传递给PPP通道,(CONFIG_PPP_MULTILINK),,反之,PPP传输通道接收到的PPP帧片段被PPP接口单元重组成完整的PPP帧. 3)在Linux-,应用程序可通过字符设备/dev/(PPPIOCATTACH)将文件绑定到PPP接口单元上,来读写PPP接口单元的输出帧,也可以用ioctl(PPPIOCATTCHAN)将文件绑定到PPP传输通道上,来
pppd源代码分析 来自淘豆网m.daumloan.com转载请标明出处.