Raspberrypi —— 实现 EC20 4G模块PPP拨号上网

一 . PPP协议

1.1 什么是PPP

PPP协议(Point-to-Point Protocol)是一种网络协议中最为基础的协议,工作于数据链路层,它是为在同等单元之间传输数据包这样的简单链路而设计的,这种链路提供了全双工操作,并按照顺序传递数据包。PPP为基于各种主机,网桥和路由器的简单连接提供一种共通的解决方法。

PPP协议包括以下三个部分:

  1. 数据帧封装方法
  2. 链路控制协议LCP,(Link, Control Protocol):它用于对封装格式选项的自动协商,建立和终止连接。探测链路错误和配置错误。
  3. 针对不同网络层协议的一族网络控制协议NCP(Network Control Protocol): PPP协议规定了针对每一种网络层协议都有相应的网络控制协议,并用他们来管理各个协议不同的需求

1.2 PPP认证方式

  1. 口令验证协商(PAP)
    PAP是一种简单的明文验证方法。NAS(网络接入服务器)要求用户提供用户名和口令,PAP一明文方式返回用户信息。
  2. 挑战-握手验证协议(CHAP)
    CHAP是一种加密的验证方式,能够避免建立连接时传送用户的真是密码。NAS向远程用户发送一个挑战口令(challenge),其中包含会话ID和一个任意生成的挑战字符串(arbitrary challenge string)。远程用户必须使用MD5单向哈希算法返回用户名和加密的挑战口令,会话ID以及用户口令,称为Secret PASSword,其中用户名以非哈希方式发送。

二. Linux中的PPP实现

2.1 Linux中的PPP架构

PPP协议工作在数据链路层,上有IP协议等网络层,下有以太网,串口等物理层,发送数据时,TCP/IP数据包经过PPP打包之后经过串口发送,接收时,从串口上来的数据经过PPP解包后上报TCP/IP协议层,Linux下PPP框架结构

在这里插入图片描述
(1)Pppd
程序是使用ppp-2.4.3源码编译得到,linux下也可以使用

sudo apt-get install ppp

直接获取,该程序用来完成PPP过程,它和Pppoe两个用户态应用程序配合起来,可以完成PppOe的拨号上网的链路协商及维护.pppd是一个用户空间的后台服务进程(daemon。pppd实现了所有鉴权、压缩/解压和加密/解密等扩展功能的控制协议。pppd只是一个普通的用户进程,pppd与内核中的PPP协议处理模块之间通过设备文件(/dev/ppp)进行通信。pppd有一个辅助工具chat,用来与GSM模组建立会话。它向串口发送AT命令,建立与GSM模组的会话,以便让PPP协议可以在串口上传输数据包。

(2)Pppoe
完成了PPPoE Discovery过程,这个过程很简单,只有PADI/PADO, PADR/PADS四个包.主要目的是相互告知MAC地址.
另外,这个程序负责接收和发送Pppoe链路的所有数据包,包括ppp协议过程的数据包,也包括正常网络应用通过网络接口ppp发送的TCP/IP数据包.在此需要了解类型为0x8863/0x8864的Socket如何工作,另外需要了解数据包如何通过PTY设备在Pppoe和PPP协议栈之间传递的.在内核模块概述中会给予描述.

(3)/dev/ppp
设备文件/dev/ppp。通过read系统调用,pppd可以读取PPP协议处理模块的数据包,当然,PPP协议处理模块只会把应该由pppd处理的数据包发给pppd。通过write系统调用,pppd可以把要发送的数据包传递给PPP协议处理模块。通过ioctrl系统调用,pppd可以设置PPP协议的参数,可以建立/关闭连接。在pppd里,每种协议实现都在独立的C文件中,它们通常要实现protent接口,该接口主要用于处理数据包,和fsm_callbacks接口,该接口主要用于状态机的状态切换。数据包的接收是由main.c: get_input统

关于其他请参考博客:Linux PPP 架构分析

2.2 PPP协议族

主要负责PPP层数据的封装、压缩与解压缩.另外,它还对普通数据包和Ppp过程的数据包进行了分流,将普通数据包提交到TCP/IP协议栈,而将Ppp过程的数据包放到/dev/ppp设备队列中,等待Pppd去收取并处理.
在这里插入图片描述
PPP 是一个分层结构。在底层,它能使用同步媒介(如 ISDN 或同步 DDN 专线),也能适用异步媒介(如基于 Modem 拨号的PSTN 网络)。在数据链路层,PPP 在链路建立方面提供了丰富的服务,这些服务以 LCP 协商选项的形式提供。在上层,PPP 通过NCPs 提供对多种网络层协议的支持。PPP对于每一种网络层协议都有一种封装格式来区别它们的报文。

三. 拨号上网流程

3.1 硬件准备

树莓派3B
EC20 4G模块
模块天线
联通电话卡

在这里插入图片描述
最左边的是我树莓派的风扇.

3.2 软件准备

因为树莓派上已经支持了4G模块的驱动,插上之后能自动检测出来,需要准备的只有应用层的pppd程序,两种方式,网上下载源码到树莓派上编译安装,另一种 sudo apt-get install ppp都可,在安装好ppp相关驱动后,就可以开始写我们的拨号脚本啦!

3.3 拨号脚本

上面提到了chat程序,它是用来向串口发送AT指令的,下载了pppd后位于系统的 /usr/sbin 目录下
下面来看具体的拨号脚本:
切换目录至 /etc/ppp/peers ,没有这个目录就自行创建,因为是在/etc目录之下,需要使用sudo或者进入root模式才能创建或者编辑,创建好之后,来到peers/下,编写我们的第一个初始化属性脚本

rasppp

# /etc/ppp/peers/rasppp

# Usage: sudo pppd call rasppp

# 连接调试时隐藏密码
hide-password

# 该手机不需要身份验证4
noauth

# 用于呼叫控制脚本
connect '/usr/sbin/chat -s -v -f /etc/ppp/peers/rasppp-chat-connect'

# 断开连接脚本
disconnect '/usr/sbin/chat -s -v -f /etc/ppp/peers/rasppp-chat-disconnect'

# 调试信息
debug

# 4G模块
/dev/ttyUSB2

# 串口波特率
115200

# 使用默认路由
defaultroute

# 不指定默认IP
noipdefault

# 不使用PPP压缩
novj
novjccomp
noccp
ipcp-accept-local
ipcp-accept-remote
local

# 最好锁定串行总线
lock
dump

# 保持pppd连接到终端
nodetach

# 用户名 密码
# user
# password
#移动,联通拨号不需要用户名密码,文末给出不同运营商的配置

# 硬件控制流
crtscts
remotename 3gppp
ipparam 3gppp

# 请求最多两个DNS服务器地址
usepeerdns



rasppp-chat-connect

# 连续15秒,收到以下字符,则退出执行
TIMEOUT 15
ABORT   "BUSY"
ABORT   "ERROR"
ABORT   "NO ANSWER"
ABORT   "NO CARRTER"
ABORT   "NO DIALTONE"

# 40秒内没有收到指定字符,则退出
# 例如 OK \rATZ,发送ATZ,希望收到的是OK
""AT
OK \rATZ

# 建立连接,联通为3gnet,文末给出各运营商配置
OK \rAT+CGDCONT=1,"IP","3gnet"

# 拨号,*99#是联通的拨号号码
OK-AT-OK ATDT*99#
CONNECT \d\c


rasppp-chat-disconnect

ABORT "ERROR"
ABORT "NO DIALTONE"
SAY "\NSending break to the modem\n"
""\k"
""+++ATH"
SAY "\nGood bye !\n"

四. 开始拨号

确保下载了pppd程序

sudo pppd call rasppp
pppd options in effect:
debug           # (from /etc/ppp/peers/rasppp)
nodetach                # (from /etc/ppp/peers/rasppp)
dump            # (from /etc/ppp/peers/rasppp)
noauth          # (from /etc/ppp/peers/rasppp)
remotename 3gppp                # (from /etc/ppp/peers/rasppp)
/dev/ttyUSB2            # (from /etc/ppp/peers/rasppp)
115200          # (from /etc/ppp/peers/rasppp)
lock            # (from /etc/ppp/peers/rasppp)
connect /usr/sbin/chat -s -v -f /etc/ppp/peers/rasppp-chat-connect              # (from /etc/ppp/peers/rasppp)
disconnect /usr/sbin/chat -s -v -f /etc/ppp/peers/rasppp-chat-disconnect                # (from /etc/ppp/peers/rasppp)
crtscts         # (from /etc/ppp/peers/rasppp)
local           # (from /etc/ppp/peers/rasppp)
asyncmap 0              # (from /etc/ppp/options)
lcp-echo-failure 4              # (from /etc/ppp/options)
lcp-echo-interval 30            # (from /etc/ppp/options)
hide-password           # (from /etc/ppp/peers/rasppp)
novj            # (from /etc/ppp/peers/rasppp)
novjccomp               # (from /etc/ppp/peers/rasppp)
ipcp-accept-local               # (from /etc/ppp/peers/rasppp)
ipcp-accept-remote              # (from /etc/ppp/peers/rasppp)
ipparam 3gppp           # (from /etc/ppp/peers/rasppp)
noipdefault             # (from /etc/ppp/peers/rasppp)
defaultroute            # (from /etc/ppp/peers/rasppp)
usepeerdns              # (from /etc/ppp/peers/rasppp)
noccp           # (from /etc/ppp/peers/rasppp)
noipx           # (from /etc/ppp/options)
timeout set to 15 seconds
abort on (BUSY)
abort on (ERROR)
abort on (NO ANSWER)
abort on (NO CARRTER)
abort on (NO DIALTONE)
send (AT^M)
expect (OK)
^M
OK
 -- got it

send (^MATZ^M)
expect (OK)
^M
^M
OK
 -- got it

send (^MAT+CGDCONT=1,"IP","3gnet"^M)
expect (OK)
^M
^M
OK
 -- got it

send (ATDT*99#^M)
expect (CONNECT)
^M
^M
CONNECT
 -- got it

send (\d)
Script /usr/sbin/chat -s -v -f /etc/ppp/peers/rasppp-chat-connect finished (pid 4042), status = 0x0
Serial connection established.
using channel 2
Using interface ppp0
Connect: ppp0 <--> /dev/ttyUSB2
sent [LCP ConfReq id=0x1 <asyncmap 0x0> <magic 0x436603d8> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x3 <asyncmap 0x0> <auth chap MD5> <magic 0xd12888a5> <pcomp> <accomp>]
No auth is possible
sent [LCP ConfRej id=0x3 <auth chap MD5>]
rcvd [LCP ConfAck id=0x1 <asyncmap 0x0> <magic 0x436603d8> <pcomp> <accomp>]
rcvd [LCP ConfReq id=0x4 <asyncmap 0x0> <magic 0xd12888a5> <pcomp> <accomp>]
sent [LCP ConfAck id=0x4 <asyncmap 0x0> <magic 0xd12888a5> <pcomp> <accomp>]
sent [LCP EchoReq id=0x0 magic=0x436603d8]
sent [IPCP ConfReq id=0x1 <addr 0.0.0.0> <ms-dns1 0.0.0.0> <ms-dns2 0.0.0.0>]
rcvd [LCP DiscReq id=0x5 magic=0xd12888a5]
rcvd [LCP EchoRep id=0x0 magic=0xd12888a5 43 66 03 d8]
rcvd [IPCP ConfNak id=0x1 <ms-dns1 10.11.12.13> <ms-dns2 10.11.12.14> <ms-wins 10.11.12.13> <ms-wins 10.11.12.14>]
sent [IPCP ConfReq id=0x2 <addr 0.0.0.0> <ms-dns1 10.11.12.13> <ms-dns2 10.11.12.14> <ms-wins 10.11.12.13> <ms-wins 10.11.12.14>]
rcvd [IPCP ConfNak id=0x2 <ms-dns1 10.11.12.13> <ms-dns2 10.11.12.14> <ms-wins 10.11.12.13> <ms-wins 10.11.12.14>]
sent [IPCP ConfReq id=0x3 <addr 0.0.0.0> <ms-dns1 10.11.12.13> <ms-dns2 10.11.12.14> <ms-wins 10.11.12.13> <ms-wins 10.11.12.14>]
rcvd [IPCP ConfReq id=0x2]
sent [IPCP ConfNak id=0x2 <addr 0.0.0.0>]
rcvd [IPCP ConfRej id=0x3 <ms-wins 10.11.12.13> <ms-wins 10.11.12.14>]
sent [IPCP ConfReq id=0x4 <addr 0.0.0.0> <ms-dns1 10.11.12.13> <ms-dns2 10.11.12.14>]
rcvd [IPCP ConfReq id=0x3]
sent [IPCP ConfAck id=0x3]
rcvd [IPCP ConfNak id=0x4 <addr 10.25.163.77> <ms-dns1 221.13.30.242> <ms-dns2 221.13.28.234>]
sent [IPCP ConfReq id=0x5 <addr 10.25.163.77> <ms-dns1 221.13.30.242> <ms-dns2 221.13.28.234>]
rcvd [IPCP ConfAck id=0x5 <addr 10.25.163.77> <ms-dns1 221.13.30.242> <ms-dns2 221.13.28.234>]
Could not determine remote IP address: defaulting to 10.64.64.64
not replacing default route to usb0 [192.168.225.1]
local  IP address 10.25.163.77
remote IP address 10.64.64.64
primary   DNS address 221.13.30.242
secondary DNS address 221.13.28.234
Script /etc/ppp/ip-up started (pid 4047)
Script /etc/ppp/ip-up finished (pid 4047), status = 0x0

拨号成功后,会返回两个DNS域名,如果拨号失败,要注意不同运营商的拨号方式是不一样的,比如电信需要填写用户名和密码,而移动和联通则不需要,拨号号码也不相同联通是 *99# ,电信是 #777,这些都需要注意.

现在,使用ifconfig查看网卡(该进程此时还不能退出(Ctrl+Z),可使用Ctrl+Z中断或者切换到其他窗口使用):

在这里插入图片描述
可以看到多了一个网卡ppp0,这其实是pppd模拟出来的一个虚拟网卡,其数据最终仍然是发送到usb0上进行处理,后面会介绍这个usb0.(有的系统没有)

现在,使用下面命切换网卡(其实是添加默认路由,使用的是ppp0)

sudo route add default gw 10.25.163.77  


使用route命令查看本地路由表

在这里插入图片描述
可以看到,默认路由已经切换成了ppp0,现在就可以使用该网卡上网了

在这里插入图片描述

如果不想切换网卡,可以使用

ping  -s  指定IP  域名

来指定使用哪一个网卡来ping
在这里插入图片描述
因为每次拨号获取到的IP地址都是不相同的,所以还可以使用

ping  -I  指定网卡  域名  

来使用指定网卡测试
在这里插入图片描述

Ctrl+c 结束进程或者重启树莓派ppp0网卡就消失啦!

五. 补充

各运营商拨号上网设置:

运营商(ISP)APN拨号号码账号密码
中国联通WCDMA(China Unicom))3GNET*99#
中国电信CDMA2000(China Telecom)#777ctnet@mycdma.cnvnet.mobi
1X网络#777card(CARD)card(CARD)
中国移动 TD-SCDMA(China Mobile)CMNET*98*1#
中国移动 CPRS(China Mobile)CMNET*99***1#


 最新版本的Linux操作系统,插上4G模块后,已经可以自己模拟出usb0网卡,并且使用AT原始拨号命令便可以直接使用usb0网卡上网,但是稍旧版本的Linux操作系统还不具备自己模拟出usb0网卡的功能,但我的系统版本是可以插上4G模块后,使用AT原始命令拨号后,便可永久自动上网,如果你问我为什么还要大费周章的使用ppp拨号上网,答案只有一个,那就是学习…


超级感谢:
https://blog.csdn.net/xingyuan1hao/article/details/89279730
https://www.jianshu.com/p/641ef413dbc0?tdsourcetag=s_pcqq_aiomsg

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值