论文关键词 : 网络共享 aal5业务 adsl接入协议 nat协议 adsl路由功能
论文摘要:本文首先阐述网络共享原理,分析目前常用的rfc1483bridged, rfc1483routed, rfc1577, pppoa, pppoe 等各种adsl接入协议类型及实现网络共享的方法。
选择 motorola powerpc 850sar 芯片作为中央处理器,搭建基本硬件开发平台; 选择 windriver 公司的tornado2.0 作为软件集成开发环境。参照 vxworks5.4操作系统的设备驱动编写规范,结合 850 cpu 的sar功能初始化, 实现sar层 end设备驱动。
以 rfc1483 协议为例, 阐述在不同的atm复用方式下,各种协议数据报文的封装处理方法。参照 vxworks5.4 操作系统网络服务子层的编写规范,给出aal5 业务网络服务子层的总体架构及相关算法、流程。在 vxworks5.4 协议栈上实现网络地址转换(nat)功能, 最后构建出一套简单的 adsl 接入共享系统。
1 引言
随着 adsl 技术的发展,adsl宽带接入已经不仅仅是一种纯粹的接入技术。家庭局域网的普及,中、小型企业电子商务的繁荣,远程办公模式的引入,都呼吁着更经济、更有效的adsl接入共享方案的出现。
如今,市场上用于 adsl 接入共享的产品非常多,如带路由功能的adsl modem、adsl 共享器、adsl 路由器等等,各adsl厂商根据实际应用的需求,在adsl 接入设备的多样性、高效性和灵活性上下功夫,进一步扩展了adsl的应用前景。www.133229.Com
实现 adsl 接入共享的方式归纳起来有以下三种,可以根据实际情况选择最合适的方案。
1. 普通 adsl modem+双网卡 pc+wingate 之类的代理服务器或防火墙软件
如图1-1所示,双网卡pc安装 wingate 之类的代理服务器或防火墙软件,一块网卡连接 adsl modem, 另一块连在局域网的 hub上,作为其它用户的ip网关。则局域网内的所有微机都可以通过这台主机访问 internet 网络。
图 1-1 双网卡 pc+adsl modem接入示意图
该方案的优点是:无需添加任何设备,仅多一张网卡,即可通过软件实现路由功能,同时,能够使用管理软件所带的安全认证、帐户管理、防火墙等一系列功能。比较适合网吧等本就需要一台服务器作为帐户管理的场所。
缺点是: 需要占用一台服务器作为数据转发设备,成本较高;数据交换的效率较低,和服务器的性能有很大关系;此外,病毒入侵或服务器本身性能不稳定,极易造成网络异常。
2. 普通 adsl modem + 共享器
所谓共享器,其实是一种集成 pppoe、nat等功能的简单路由器。图 2-2 所示的组网方案中,共享器取代了前一个方案中双网卡 pc 的地位。
采用这种方案后,可以节省一台服务器以及相关软件的花费,较第一种方案来说,确实经济很多,也不用再担心病毒入侵、服务器不稳定等问题了。很多共享器本身就带多个 lan 口,无需再添置 hub 或 switch 等设备即可供多台微机使用,对于家庭局域网或小型办公场所非常合适。
图 1-2 共享器+ adsl modem接入示意图
3.带路由功能的 adsl modem
带简单路由器功能的adsl modem 集成了 adsl 接入功能及网络共享技术。如图1-3所示,局域网用户仅需将自身的ip网关指向设置在adsl modem以太网接口上的ip地址,即可实现与外部网络的互连。
由于adsl 接入和路由两种功能集成在同一设备中,减少了中间的数据转发环节,传输效率会更高一些,配置及调试起来也方便很多。此外,用一块 cpu 就可以实现 adsl接入协议及简单路由等软件功能,硬件成本降低很多,价格比起 adsl modem + 共享器 当然更有优势了。
图 1-3 带简单路由功能的adsl modem接入示意图
本文将首先介绍网络共享原理,然后逐个分析目前常用的各种 adsl 接入协议以及实现共享的方式。最后以 motorola 850sar + vxworks5.4为开发平台,设计一套带简单路由功能的 adsl 接入设备,重点阐述atm sar 层驱动的编写、aal5 业务、各种接入协议以及带宽共享功能的软件实现。
2 网络共享原理
2.1 私有网络地址和公有网络地址
私有地址是指内部网络(局域网内部)的主机地址,而公有网络地址是局域网的外部地址(在因特网上的全球唯一的ip地址)。因特网地址分配组织规定以下的三个范围网络地址保留用做私有地址:
10.0.0.0 —— 10.255.255.255
172.16.0.0 —— 172.31.255.255
192.168.0.0 —— 192.168.255.255
也就是说这三个范围网络的地址不会在因特网上被分配,但可以在一个企业(局域网)内部使用。各个企业根据在可预见的将来主机数量的多少,来选择一个合适的内部网络地址。不同的企业,他们的内部网络地址可以相同。如果一个公司选择上述三个范围之外的其他网段作为内部网络地址,则有可能会引起路由的混乱。
2.2 nat原理
nat(network address translation)网络地址转换,是一个ietf标准,允许一个机构以一个公有网络地址出现在internet上。nat将每个局域网节点的私有网络地址转换成一个公有网络地址,反之亦然。它也可以应用到防火墙技术里,把私有地址隐藏起来不被外界发现,使外界无法直接访问内部网络设备,同时,它还帮助网络可以超越地址的限制,合理地安排网络中的公有网络地址和私有网络地址的使用。
napt (network address and port translation) 网络端口地址转换,可以将外部网的公有 ip 及端口号与内部网络的私有网络ip 及端口号相互映射。 通过这种端口重定向方式实现的 nat 映射功能,可以将来自公共网络的服务请求映射到内部网络某台微机上。
例如,如果公司想以内部网络中的主机a 作为对外公开的web服务器,就得告诉nat设备将任何访问其公网地址80端口的连接重新定向为到内部网络a主机地址的80端口。如下图所示
图 2-1 nat 端口映射应用示意图
3 adsl 连接协议概述
3.1 rfc1483 bridged 接入方式
rfc1483标准的制定是为了实现多种协议数据包在atm 的 aal5 层的封装传送。在协议模型上,rfc1483-bridged方式在数据链路层对 mac 帧进行 llc/snap 或vcmux 的封装,以此来指明上层所应用的协议类型,因此可以适用于网络层上的多协议传送。在形式上,它仿真了以太网的桥接功能,相当于将用户侧的终端设备直接挂接在网络侧的网桥设备上。
由于adsl接入设备配置为桥连接方式,理论上来说,设备后可以接多台配置为公网ip地址的微机,这些微机都可以通过网关直接接入 internet 网络中。但实际上可分配的公有 ip 地址并不多,很多服务提供商限制了每根线上可分配的 ip 个数,因此只有将ip 地址设在adsl 接入设备的 wan 端, 然后通过 nat 的方式来共享有限的 ip 资源,这就是目前较为常见的 1483bridged+nat 接入方式,又称为桥路由方式,其接入模型如图3-1所示。
图 3-1 1483bridged+nat 接入示意图
3.2 rfc1577 经典ipoa接入方式
严格的说,rfc1577 并非一种接入标准,它规定了在 atm 的aal5上使用的地址解析机制,是对 rfc1483 routed 接入方式在 atmarp 实现细节的补充。在协议模型上,rfc1577不再转发类似arp 协议的各种以太网报文, 而是通过和网络指定的arp 服务器交互 atmarp信息获得下一跳 ip 地址所对应的 atm 地址,然后采用 rfc1483 llc/snap 或 基于vc 的复用方式对routed报文进行封装处理。
rfc1577 一般用于需要静态 ip的商业用户, 和 rfc1483bridged方式一样,可以采用带 nat 功能的设备实现多台微机共享带宽。
3.3 rfc2364 ppp over atm 接入方式
pppoa接入技术根据rfc2364封装标准对ppp包进行aal5层封装处理,形成atm信元流,传送到网络侧的宽带接入服务器上,完成授权、认证、分配ip地址和计费等一系列ppp接入过程。
同样,可以采用带 nat 功能的设备实现多台微机共享带宽。此外,当服务商是根据 ppp 接入的时间进行计费时,还需要考虑 adsl 设备是否具有按需拨号(dod功能)及自动断开功能,这样可以避免无数据访问时系统仍占用带宽,浪费网络资源及增加不必要的费用开支。
3.4 rfc2516 pppoe接入方式
早期的 pppoe 接入方式,拨号程序一般放在 pc 机上,adsl modem 配置为简单的 rfc1483bridged 桥接方式,由 pc 机使用pppoe客户端程序(比较常见的有 enternet300、raspppoe等)发起 ppp 拨号请求并获得动态的公网 ip 地址。其接入模型如下图所示
图 3-2 pppoe 接入示意图
为了实现多台微机带宽共享,需要将 pppoe 客户端呼叫例程集成至 atur端,其后加上 nat 地址转换机制。目前,一般带路由功能的 adsl 接入设备都具有这样的功能。
4 开发平台的选择及搭建
4.1 产品定位
鉴于目前市场上面向低端用户的 adsl 接入产品较多,价格竞争非常激烈, 利润空间已急剧减缩。我们希望开发一款针对中高端用户使用的 adsl 路由器产品,除了实现普通 adsl 接入及简单 nat、防火墙等功能外,还具有路由器产品的 vpn、ipsec、服务映射、动态路由更新协议等功能,具有和 cisco 兼容的配置命令集,实现即配即用,便于用户随时进行监控管理。
4.2 硬件开发平台的选择
通过调研,我们找到几款符合需求的cpu芯片,如 motorola 的 powerpc 850sar、 intel 的 ixp225、samsung 的s5n89xx系列芯片,virata 等。这几款芯片在性能、价格等方面的综合比较如下表所示:
cpu
core
提供评估参考板
软件方面支持
价格
virata
arm
有
全套
低
motorola ppc850sar
ppc850
有
有bsp、aal5驱动参考例程
适当
intel
ixp225
arm7
有
有bsp,aal、atm业务api等模块
高
samsung
s5n89xx
arm7
需购买
有bsp,aal2、aal5、atm业务等api
高
表 4-1 硬件平台综合比较表
若从成本方面考虑,选择 virata 芯片比较合适,而且厂方提供了自己的操作系统及全套开发源代码,几乎已是半成品。但测试中感觉部分协议、功能不够完善,控制台人机界面也不符合要求,还需要进行后续开发,而其提供的开发环境不够理想,代码可移植性也比较差,不利于技术积累。
intel ixp225、samsung s5提供的软件支持较多,已支持for tornado 的 1483bridged 和 pppoa 等协议,也有 nat、pat等网关路由应用模块,此外,还支持 voice over aal2 功能。但芯片价格相比之下也高出很多。考虑到目前 voaal2 的应用并不明朗,很少有局端支持此项功能,所以暂不考虑这两款芯片。
motorola powerpc850sar 是850 系列芯片针对 adsl 接入推出的专用简化版本(此后又推出了性价比更高的 850dsl 芯片),价格较低,其提供的软件方面支持虽然较少,但已基本符合我们的需求,后续开发的难度不会太大。如果选择通用的 tornado开发套件进行开发,以后可以方便地迁移至 intel ixp225、intel ixp425或samsung 等系统平台,代码的重复利用率高。由此,我们决定采用 powerpc 850sar作为核心部件,adsl接入前端则选择兼容性较好的 alcatel dsp芯片组,总体架构如图4-1所示。
4.3 软件开发平台的选择
软件上目前流行的嵌入式操作系统有 vxworks、psos、rtos、qnx、ullinux 等,由于vxworks 对 powerpc、arm 都有良好的支持,已经提供了针对 motorola 开发评估板(ads板)的 bsp 组件,并且其集成开发套件 tornado 使用起来非常方便,可以有效地节省开发周期,也便于以后系统迁移,所以决定采用这款操作系统。
4.4 开发平台搭建简述
开发平台的准备包括硬件平台调试及底层驱动编写,因为篇幅有限,硬件平台的调试略过,底层驱动及软件开发环境的搭建工作仅作简单描述:
1)针对目标板与ads板在 sdram、flash、ethernet等芯片的不同,更改相应的外围器件驱动,生成新的 bsp驱动,并编译生成 vxworks 系统的boot 代码,使其可以在新的目标板上运行。
2)在此 bsp 基础上创建 bootable 工程,编译 bootable 程序代码,使其可以正常下载至目标板中运行,并能正常启动 target shell。此后,就可以建立downloadable 工程,将应用程序以任务执行方式在目标板中进行调试。
3)编写 alcatel dsp 驱动,调通 adsl 物理层、atm层(utopia接口)的连接。这部分工作的要点在于 alcatel dsp 内部寄存器和提供目标代码都是 little endian 模式,而 powerpc 默认的总线是 big endian 模式,下载时需要对相应数据做字节或字交换。
图4-2 adsl 共享接入系统软件架构示意图
这些部分调试完成后,就可以着手 sar end驱动、网络层接口及网关应用层的开发了。软件架构系统如图4-2所示(深黑色所示部分为本文所要着重阐述的sar end驱动、adsl 业务驱动及 nat 实现等模块)
5 sar end 驱动的编写
sar 驱动模块是参照 vxworks 系统的 end 驱动模板编写的,基本符合 mux 接口规范,其中主要的几个功能实现。
5.1 utopia接口初始化
850sar 内部参数的全局联系结构。是 scc 各个参数表间的联系,由左至右是从上级表到下级表的关系,代码实现中,对这些参数表的初始化顺序则要相反,即先初始化下级表,再初始化上级表。具体初始化流程如下:
5.2 加载及初始化函数
sarendload 由系统在加载muxdevendload 时间接调用,是 end 驱动第一个被加载的例程,它根据入口参数 unit,对相应aal5通道的atmif结构表进行初始化,并调用saraal5add 增加相应的通道。
sarendstart 由系统在运行 muxdevendstart 时间接调用, 它根据入口参数unit 调用 saraal5start 函数激活相应的 aal5 通道,允许其正常开始收发。
saraal5add 增加一条 aal5通道,初始化这条通道的收发缓冲区,缓冲区描述字, tct 及 rct 表中的相关参数值。
saraal5start 激活一条aal5通道,根据通道对应的atmif结构设定 pvc, 上行速率。将通道 pvc mask 放入 lookup 表中,激活该通道进行接收;发送 tx_active 命令,激活该通道进行发送。
5.3 停止及卸载函数
在系统执行 muxdevunload 或 muxdevstop 时间接调用这两个函数。
sarendunload 释放这个设备所占的 endobject 结构资源。但通道所占的内存资源并没有释放。
sarendstop 停止这个接口。并调用 saraal5stop 函数关闭这条通道,执行与sarendstart 相反的操作。
saraal5stop 解激活并关闭这条通道。将通道 pvc mask 移出 lookup 表,解激活该通道,使其停止接收;发送 tx_deactive 命令,解激活该通道,使其停止发送。
5.4 数据发送函数
函数名称:sarendsend
功能: 将数据发送到相应的aal5通道中。
入口参数:指向通道的end object设备结构指针,指向待发送的数据包 mblk 结构指针。
返回: 发送成功,返回 ok;
阻塞状态返回 end_err_block;
其他情况返回 error。
流程简介: 将 mblk 指向的数据包进行加封装操作,将指针及长度填入当前发送 bd 中即可。(注:为防止重入,使用到发送指示信号量,并在修改阻塞状态时给予中断保护)
5.5 中断控制流程
scc 工作在 utopia 模式下的中断联接在 idma1上,使用函数
intconnect(iv_idma1,(voidfuncptr)sarintr,0)
就能够在 sar 发生中断时调用 sarintr 函数。此时我们将轮询整个 sar中断表,并对相应中断进行处理,为避免该中断过多占用系统资源,我们将其放置在一个 netjob 任务中。同时,进入该任务后,屏蔽全局中断,直到所有的中断事件处理完毕。
5.6 数据接收处理
当 utopia 接口收到来自于 dsp的数据后,会提取出 atm 报文头部信息,如果是 aal5 通道报文,则将报文存入相应的数据缓冲区中,设置相关寄存器值,并产生utopia数据接收中断。
系统收到中断请求后,将会进入 5.5 所示的中断例程进行处理,判断是接收事件时,提取产生事件的通道号,计算出该通道对应的 atmif 结构起始地址,作为参数调用 sarrecv 函数,在函数中进行数据报文处理。
6. aal5 业务模块的实现
作为系统(vxworks)协议栈和sar end驱动模块之间的接口,atm aal5业务网络服务子层主要完成如下功能:
1)发送:向系统注册1483bridged、1483routed、atmarp、pppoa、pppoe等不同类型接口(interface),根据各个接口的不同类型,对系统ip数据报文进行atm链路封装,将封装后的数据报文发送到驱动模块并同时指示发送的vc通道;
注: 因为 1483bridged 封装的是以太网帧,解封装后可视为正常的以太网数据帧,直接交由协议栈处理,所以我们不需要再注册 1483bridged 协议类型接口。
2)接收:向系统注册业务类型,接收系统送来的数据报文(由驱动模块接收,并由系统根据接收的数据报文业务类型进行分发),根据接口属性对数据报文进行解封装后提交到系统协议栈或者交由其他模块处理,
3)控制:接收系统对于接口上的控制操作(主要是根据vxworks network services 提供的规范完成),通过向mux接口注册重发例程实现数据报文重发。
6.1 vxworks 网络服务子层编写规范
vxworks 网络服务子层介于从 osi 规范的网络层和链路层之间,主要负责处理系统网络协议栈和mux 接口之间的数据报文。它包括接口初始化、数据结构初始化、数据收发处理、错误报告和流量控制(可选)等部分。
6.1.1 接口初始化
vxworks 系统协议栈通过调用网络服务子层初始化例程(函数名称为 xxxattach())来激活相关网络接口。在这个例程开始处,我们需要先用 muxbind 函数将该服务子层绑定至相关的网络接口驱动上,使该服务子层能够从 mux 层收发数据报文。
6.1.2 数据结构初始化
服务子层在收发相关数据报文时,可能需要申请或释放网络内存块。为避免系统正常运行期间频繁使用系统内存块操作导致效率降低或稳定性降低,可以在初始化时预先申请一个内存区域,由 netbuflib 所提供的net buffer控制机制进行管理。
其它如接口的状态、服务子层数据封装类型、mux接口初始化 cookie、服务子层地址映射表等参数结构也需要在这一步进行初始化。
6.1.3 数据收发处理
如上所述,网络服务子层通过 muxbind 函数将数据接收例程绑定至底层设备驱动。底层设备驱动接收到报文后,通过调用 stackrcvrtn 函数将数据经由 mux 层查找特定协议类型返回至服务子层。服务子层处理该报文之后如果返回 false,则系统将报文发往其它服务子层继续处理,否则,该报文被丢弃。
数据报文被封装成 mblk 形式从协议栈上层发送至网络服务子层,网络服务子层对报文进行处理后,再调用 muxsend 或 muxtksend 函数将报文通过 mux 层发送至该接口设备驱动。在这期间,网络服务子层可以通过调用该接口设备指定的地址解析函数获得二层目标地址,然后对数据帧进行二层封装。
具体的数据收发处理实例可参见 6.2.3 aal5 service 协议数据处理流程。
6.1.4 错误报告
当设备驱动层向网络服务子层汇报收发或其它错误时,网络服务子层可以通过回调 stackerrorrtn 函数向上层报告这个错误。
6.1.5 设备控制
设备驱动程序需要增加相应的控制接口函数(如 xxxioctrl), 并注册至 mux 层,网络服务子层就可以通过调用 muxioctl 控制底层设备驱动。
6.2 aal5 业务service的实现
service 层主要实现如下相关协议类型:
atmarp service. 用于收发 atmarp 报文,绑定类型为 0x1577
pppoe service, 用于收发 pppoe 报文,绑定类型为 0x8863,0x8864
pppoa service, 用于收发 pppoa 报文,绑定类型为 0x2516
如6.1 所介绍的,我们首先需要向 mux 注册(绑定)这些 service,然后在 service 的收发中对相关协议的数据报文进行处理。
6.2.1 向vxworks mux 层注册service
1) 根据协议类型,初始化封装数据、大小等值
2) 用muxbind 函数绑定接收函数,使某接口收到相应类型的报文时能够提 交该函数处理。例如(代码摘选自 atmsrv.c atmsrv1483routedattach函数),绑定 atmarp 时作如下调用:
#define mux_proto_atmarp 0x1577
int unit = 1;
muxbind(“pvc”, unit ,(funcptr) atmsrv1483routedrcvrtn, null,null,null, mux_proto_atmarp, "atmsrv1483routedrcvrtn", unit);
/* 此处,把 atmsrv1483routedrcvrtn 函数绑定至pvc1接口,当pvc1收到 0x1577 类型的数据报文时,就会自动提交给该函数进行处理 */
3) 初始化 service 网络参数,定义报文发送时的处理函数,并向 mux 层注册该service,例程如下:
struct ifnet* pifp = &atmsrvctrl[unit].ifp;
bzero ((char *) pifp, sizeof (struct ifnet));
pifp->if_unit = unit;
pifp->if_name = ifname;
muxioctl(atmsrvctrl[unit].pcookie, eiocgflags, (caddr_t)&flags);
pifp->if_flags = flags;
if (muxioctl(atmsrvctrl[unit].pcookie, eiocgmib2, (caddr_t)&mib2tbl) == error)
return (error);
pifp->if_mtu = mib2tbl.ifmtu;
pifp->if_baudrate = mib2tbl.ifspeed;
pifp->if_type = mib2tbl.iftype;
pifp->if_addrlen = mib2tbl.ifphysaddress.addrlength;
pifp->if_flags |= iff_broadcast;
if (muxioctl (atmsrvctrl[unit].pcookie, eiocghdrlen, (caddr_t)&ifhdrlen)!= ok)
pifp->if_hdrlen = 0;
else
pifp->if_hdrlen = (uchar)ifhdrlen;
pifp->if_init = null;
pifp->if_ioctl = ifioctrl;
/* 在这里定义该协议类型报文发送时要调用的处理函数 */
pifp->if_output = atmsrv1483routedservice;
pifp->if_reset = null;
pifp->pcookie = atmsrvctrl[unit].pcookie;
pifp->if_resolve = null;
pifp->if_flags |= (iff_up | iff_running | iff_notrailers | iff_noarp);
if(atmif[unit].ifp)
if_dettach(atmif[unit].ifp);
/* 向 mux 层注册该 service */
if_attach (pifp);
6.2.2 service 数据结构初始化
我们定义 aal5 业务网络服务子层的数据结构如下:
typedef struct atm_srv_ctrl
{
int tlinktype; /* 定义协议类型*/
int encaplength; /* 定义该协议封装用的 pdu 大小*/
char encapdata[50]; /* 该协议使用的 pdu 内容 */
end_obj * pcookie; /* 底层设备驱动单元索引 */
struct ifnet ifp; /* 注册后返回的网络服务子层索引*/
}atm_srv_ctrl;
其中:
tlinktype 定义的协议类型主要有rfc1483bridged, rfc1483routed, atmarp,pppoa,pppoe等。在 atmifattach 例程中,就是将该值作为协议类型参数调用 muxbind 函数的。