基于Android的4over6技术驱动程序设计与实现
摘要:全球IPv4地址已经分配殆尽,实现由IPv4向IPv6平滑过渡是制约下一代互联网发展的关键问题。4over6隧道技术目前已成为解决接入网IPv6过渡问题的一项主流技术方案。4over6支持IPv4通信节点间建立双向透明的IPv4 over IPv6隧道,使IPv4节点能跨越IPv6网络实现互访,维护了网络通信端到端特性和底层隧道实现对上层应用的透明性,满足了终端用户对IPv6过渡时期保持IPv4网络通信的基本需求。作为IPv6接入网组成部分之一,解决移动互联网IPv6过渡问题对推动全网IPv6过渡而言具有重要意义。本文针对移动互联网IPv6过渡场景,对主流智能移动终端平台――Android进行研究,针对其特点提出40ver6驱动程序♀设计与实现,并给出测试结果,希望能为研究人员以及开发者提供参考。
关键词:计算机软件;4over6;Android;驱动
中图分类号:TP311 文献标识码:A DOI:10.3969/j.issn.1003-6970.2015.02.025
0 引言
基于IPv™4协议的互联网经过20多年的飞速发展,在全球范围内取得了巨大成功。然而,随着互联网规模的持续增长,尤其是移动互联网和物联网的扩张和新业务发展,基于IPv4协议的网络环境已经难以应对,开始突显地址资源紧张、路由可扩展性不足等问题。其中最关键的问题即是IPv4地址资源严重匮乏。2011年2月,IANA将最后5个可用的/8 IPv4地址池分配给了区域性互联网注册机构RIR,标志着全球IPv4地址已全部分配完,可用IPv4地址宣布告罄。
下一代网络基础协议IPv6具有巨大的地址空间、更好的安全性和移动特性,其全面部署是解决当前互联网面临的网络编址等技术难题的最佳方案。然而,由于IPv4与IPv6间缺少内在兼容性,网络在由IPv4向IPv6迁移的过程中被迫面对诸如地址空间不匹配、异构协议网络节点无法互通等问题。
针对IPv6过渡中面临的关键技术问题,国际标准化组织互联网工程任务组IETF(Inernet EngineeringTask Force)发布了多种IPv6过渡技术标准方案。目前IPv6过渡技术以IPv4-over-IPv6隧道为主要发展方向,而在IPv4-over-IPv6隧道方案中,4over6隧道技术通过跨IPv6网络的IPv4地址配置技术DHCPv4-over-IPv6,以及在网络层实现的IPv4-in-IPv6协议报文封装/解封装机制,实现了IPv4终端与IPv4互联网间的双向隧道,使IPv4终端对穿越IPv6网络的通信过程毫无感知,因✌而维护了网络通信端到端的特性,保持了IPv4、IPv6异构网络独立性和各自路由可扩展性,满足了终端用户对IPv6过渡时期保持IPv4网络通信的基本需求。
目前国际上主要针对接入网场景中以太网IPv6过渡问题展开研究。作为接入网的组成部分之一,解决移动互联网过渡面临的技术难题对推动全网IPv6过渡而言具有重要意义。本文主要面向移动互联网IPv6过渡场景,探讨4over6技术在以Android为代表的智能移动终端上的应用,希望能为IPv6过渡研究人员与智能移动终端应用开发者提供参考。
1 4over6基本原理
4over6隧道技术通常部署在互联网服务提供商ISP(Internet Service Provider)的IPv6网络中,其模型如图1所示。4over6 Customer Edge(4over6 CE)为4over6隧道发起点,既可以是IPv4/IPv6双栈(Dual-stack)主机,也可以是双栈用户侧设备CPE(Customer Premises Equipment)。位于IPv6接入网和IPv4因特网之间的双栈路由器则是4over6 Border Relay(4over6 BR)。4over6 CE和40ver6 BR之间通过IPv4-over-IPv6隧道传输IPv4报文,使IPv4主机或双栈主机跨越IPv6网络与IPv4互联网实现互访。
4over6方案采用DHCPv4-over-IPv6技术建立IPv4-over-IPv6隧道。在DHCPv4-over-IPv6技术中,所有DHCPv4消息均通过IPv6协议进行传输,因而基于DHCPv4的IPv4地址配置交互过程能在IPv6网络中完成。4over6 CE通过DHCPv4-over-IPv6从4over6 BR处获取公网IPv4地址,而该地址也由4over6 BR向IPv4互联网中进行广播。因此4over6 CE虽然处于IPv6网络中,但对于IPv4互联网中的其他IPv4节点而言却是可达的,因此4over6 CE与IPv4互联网之间能实现双向通信。该特性对于移动互联网中的一项核心服务――服务商向用户手机进行消息推送来说至关重要,因此4over6是十分适合于移动互联网IPv6过渡场景的技术方案。
考虑到智能手机对降低计算能耗、提升续航能力的需求,目前面向以太网的4over6技术的软件实现并能不完全适用,需要针对智能手机的特点进行轻量级改造。对Android系统而言,由于内核具有较强可扩展性,因此可考虑将4over6核心技术实现在Android内核中,作为系统级网络接口驱动程序运行,在最大程度上降低运行4over6技术实现产生的能耗。
2 4over6驱动程序设计与实现
目前智能手机的处理器芯片(主要是射频通讯控制芯片Baseband Processor,简称BP芯片)和操作系统OS(Operating System)中的网络协议栈均需要支持IPv6协议。Android的内核是基于2.6以上版本的Linux内核实现,本身对IPv6具有完善的支持。然而,许多Android 2.x与3.x版本的系统在编译时默认不开启IPv6相关模块,致使使用Android 2.x与3.x版本OS的手机并不能访问IPv6网络。 从Android 4.0开始,Android系统已对IPv6提供了完善的支持,不仅完整编译了IPv6协议栈,而且其DHCP模块也增加了对无状态DHCPv6的支持。然而,由于目前许多手机BP芯片缺乏对PPPv6的支持,并且电信运营商对于GSM/3G侧的IPv6支持仍处于实验中,尚未部署到现网,现阶段很难建立Android手机在GSM/3G侧的IPv6环境。尽管如此,Android4.2.2版本对于WiFi侧使用IPv6的支持度仍然较高127-33],因此,本文选择Android 4.2.2版本系统、3.4.0版本内核,针对其WiFi接口进行4over6驱动程序实现,使其支持传输IPv4-in-IPv6报文,为上层IPv4应用提供轻量级、透明化的IPv4-over-IPv6隧道服务。
40ver6驱动程序应用场景如图2所示。图中IPv6网络既可以是全球IPv6互联网,也可以是本地IPv6网络(但要求具有全球IPv6可达性)。Android移动终端通过WiFi方式接入这个IPv6网络。
在IPv6网络与IPv4互联网交界处是4over6 BR,负责与Android终端建立并维护IPv4-over-IPv6隧道,同时作为DHCPv4服务器,为Android终端分配公网IPv4地址。在该环境中,4over6驱动程序运行在Android终端上,主要负责处理DHCP报文与IPv4报文,使其能跨越IPv6网络在Android移动终端与4over6 BR间进行传输。
4over6驱动程序按功能可划分为CRA模块与封装/解封装模块,其在Android系统中的位置如图3所示。下面将对各模块的设计与实现分别进行说明。
2.1 CRA模块
由于Android系统GSM侧(即2G/3G)的IP地址并不是通过DHCP过程、而是通过PPP协议分配的,因此本节仅讨论Android系统在WiFi侧的DHCP过程。该过程主要涉及到两个状态机――WiFi状态机和DHCP状态机。两种状态机在Framework层面的实现分别位于源代码根目录下/frameworks/base/wifi/java/android/net/wifi目录下的全部文件,以及源代码根目录下/frameworks/base/core,java/android/net目录下的DHCP相关文件中,包括:Dhcplnfo.aidl,DhcplnfoInternal.java,Dhcplnfo.java,DhcpStateMachine.java。WiFi状态机与DHCP状态机使用基于Android接口描述语言AIDL(Android Interface Definition Language)及远程调用的message机制进行通信。
Android系统中DHCP交互过程如图4所示。首先,在Android系统接入到一个无线网络中后,WiFi状态机会进入ConnectingState状态。在该状态下,WiFi状态机首先会使能IPv6模块,之后判断用户是否配置了使用静态IP,若为否,则WiFi状态机在新建一个与本接口关联的DHCP状态机,并通过message消息开启该DHCP状态机。DHCP状态机启动后,调用JNI函数runDhcp()进行DHCP流程,并接收DHCP配置信息,该配置信息之后将通过message消息发送给WiFi状态机,消息标识为CMD POST DHCP ACTION。WiFi状态机在ConnectingState状态下收到该消息后,利用函数handleSuccessfullpConfiguration()进行IP地址、默认网关、DNS服务器等接口配置,完成后转入ConnectedState状态。DHCP状态机调用runDhcp()时,该函数会建立一个dhcp client守护进程,用于发出DHCP请求以及接收DHCP服务器返回的DHCP配置报文。该进程将一直处于阻塞状态,直到这个DHCP过程完成(无论结果是成功还是失败)。如果成功获取DHCP配置信息,则返回true,将配置信息交回给DHCP状态机;如果DHCP过程失败,则返回fail信息。
CRA模块负责处理的是系统组件dhcpcd的DHCPv4过程。针对不同的DHCP报文(主要是不同传输方向上的DHCP报文),CRA模块进行不同的处理。按报文传输方向区分,具体处理方式如下:
1.DHCP DISCOVER和DHCP REQUEST报文
报文在UDP层,源端口为67,目的端口为67;在IP层,源地址0.0.0.0,目的地址255.255.255.255,为流出方向上的IPv4广播报文。CRA模块在该报文进入系统路由进程前截获该报文,去掉其IPv4包头,将其替换为IPv6包头,其源IPv6地址字段填为本机IPv6地址,目的IPv6地址字段填为4over6 BR端IPv6地址,其他字段按照IPv6协议标准填充(即模拟IPv6网络层协议栈处理过程,下面所有IPv4/IPv6包头替换均采用此方法)。之后CRA模块再将该报文放行,使之进入系统路由进程。由于该报文已由UDPv4报文变为UDPv6报文,系统会将该报文作为IPv6报文,在查询路由表后发往网络链路。
2.DHCP OFFER和DHCPACK报文
报文在UDP层,源端口为67,目的端口为67;在IP层,源地址为40ver6 BR端IPv6地址,目的地址为本机IPv6地址,为流入方向上的IPv6单播报文。CRA模块在该报文进入系统路由进程前截获该报文,去掉其IPv6包头,将其替换为IPv4包头,包头源地址按报文负载中的SIADDR(服务器IPv4地址)字段填充,目的地址按报文负载中的YIADDR(服务器分配给本机的IPv4地址)字段填充,包头内其他字段按照IPv4协议标准填充。之后CRA模块再将该报文放行,使之进入系统路由进程。由于该报文已由UDPv6报文变为UDPv4报文,系统会将该报文作为IPv4报文,在查询路由表后转交给dhcpcd挂接在接口IPv4侧的处理函数。dhcpcd获取该报文后对其进行正常的DHCP处理,如配置本机地址、处理负载携带的Option(包含子网掩码、IP地址租约时长、到达网关的静态路由、DHCP服务器地址、DNS服务器地址)等。 对于上述两类处理流程,本文采用Android内核提供的Netfilter机制进行实现。Netfilter是Linux内核提供的处于硬件层和网络层之间的接口方法,在Android系统中得到了继承。Netfilter能对报文原始数据进行控制和操作。Netfilter提供了处于网络流程不同层次的五类函数挂钩,亦称为检查点,如图5所示。在这些检查点上,开发者可以挂载自己的处理函数,进而在不同层次上实现对报文的自定义操作。这五类HOOK分别如下:
NF_IP_PRE ROUTING:在报文进入路由进程之前执行;
NF_IP_FORWARD:在报文向另一个物理设备(可能为本地设备,也可能为网络链路中的下一跳设备)转发之前执行;
NF_IP_POST_ROUTING:在报文流出本机之前执行;
NF IP LOCAL IN:在流入本地的报文完成路由过程之后执行;
NF_IP_LOCAL_OUT:在本地流出方向报文进入路由进程之前执行。
每个注册在上述检查点的钩子函数。经过处理后都将返回下列值之一,告知Netfilter核心代码处理结果,以便对报文采取相应的动作:
NF ACCEPT:继续正常的报文处理;
NF DROP:将报文丢弃;
NF_STOLEN:由钩子函数处理了该报文,不要再继续传送;
NF_QUEUE:将报文入队,通常交由用户程序处理;
NF REPEAT:再次调用该钩子函数。
在这里本文主要采用了NF IP LOCAL OUT挂钩来处理dhcpcd发出的DHCP报文,以及NF IP PREROUTING挂钩来处理从物理接口上收取到的DHCP报文。其中主要涉及到两个关键函数:
1.unsigned int hook_func_in(unsigned int hooknum,struct sk_buff*skb,const struct net_device*in,conststruct net_device*out,int(*okfn)(struct sk_buff*))
该函数挂接在NF_IP_PRE ROUTING处,主要完成流入方向上DHCPv4-over-IPv6报文的IPv6解封装功能,解封装后报文被还原为UDPv4报文。函数运行后返回NF ACCEPT,Netfilter放行报文使其进入IPv4路由进程,进而递交给上层dhcpcd进程。
2.unsigned int hook func out(unsigned int hooknum,struct sk buff*skb,const struct neLdevice*in,conststruct net_device*out,int(*okfn)(struct sk buff*))
该函数挂接在NF IP LOCAL OUT处,主要对流出方向上的DHCPv4报文进行IPv6封装,使其变成DHCPv4-over-IPv6报文。函数运行后返回NF ACCEPT,Netfilter放行报文使其进入IPv6路由进程,进而转交物理接口发往网络链路。
2.2 封装/解封装模块
封装/解封装模块负责进行IPv4报文的IPv6报头封装,以及IPv4-in-IPv6报文的IPv6报头解封装。本文在Android系统中建立了一个新的4over6虚接口,该接口在抽象层面上处于实际网络接口的上层,封装/解封装模块正是实现在4over6虚接口中,负责处理从4over6虚接口处通过的所有IPv4报文及IPv4-in-IPv6报文。
图6所示为4oer6虚接口对不同方向上报文的处理,实线箭头所示为IPv4报文,虚线箭头所示为IPv4-in-IPv6报文。图6中左图所示为封装流出方向上的数据流处理,其中右图所示为解封装流入方向上的数据流处理。
封装/解封装模块的封装及解封装过程具体如下:
1.封装过程
对于从上层应用传递下来的IPv4数据,在进入网络层时,内核通过路由表来控制数据的流向,内核通过查找路由表来获取报文流向的进一步信息。在4over6驱动程序初始化的过程中,将4over6虚接口设置为IPv4路由的默认接口,则所有IPv4类型的报文都会进入到4over6虚接口中来进行处理。封装模块在4over6接口注册的发送函数中,完成对报文IPv6头部的封装。之后,再将封装后的IPv6报文移交至内核处理。报文经过内核网络协议栈后,会从设备的IPv6侧网络接口进入网络链路。
2.解封装过程
Android内核在处理报文进入网络协议栈时,会先分析分组的类型,以便根据协议类型(也就是分组中的下一协议字段Next Header),将分组传递给网络层相应协议的处理函数处理。在此处需要在既有的协议类型基础上,增加40ver6协议类型(即IPv4-IN-IPv6协议类型)。当内核发现IPv6分组头部的下一协议字段是4over6协议字段时,就会将分组交由该协议指定的函数处理,也就是解封装模块在内核中注册的4over6协议的接收函数。在该函数中,解封装模块完成报文的IPv6解封装,然后再转交给内核。报文经过内核网络协议栈后,会由内核递交给在该报文对应网络层位置处监听的上层应用。
上述过程涉及到的关键函数如下:
1.int inet6_add_protocol(const struct inet6_orotocol*prot,unsigned char hum)
该函数是内核提供的IPv6侧下一协议注册函数。通过该函数注册IPv4-IN-IPv6协议类型,这样当内核收到IPv6报文,发现其下一协议字段是IPv4-1N-IPv6类型时,会将报文交给由本文指定的public40ver6 rcv函数进行处理。 2.int public4over6 tunnel xmit(struct sk buff*skb.struct net device*dev)
该函数注册在net_device_ops类型的结构中,当报文被发到4over6虚接口后该函数将自动被调用,用于对IPv4报文进行IPv6头的封装(模拟IPv6协议栈操作)。之后报文将被4over6接口转交给内核进行路由(调用ip6route output()函数)。之后报文经由内核转交给实际接口,发往网络链路(调用NF_HOOK宏,向sk_dst(skb)->output指向的出口发出报文)。图7为4over6虚接口封装发包过程示意图。
3.int public40ver6_rcv(struct sk_buff*skb)
该函数注册在inet6_protocol类型的结构中,在IPv4-IN-IPv6协议类型被注册时,作为协议对应的处理函数一起注册。当实际接口收到IPv6报文时,检查到下一协议为IPv4-IN-IPv6类型,便会将该报文交给该函数进行处理。在该函数中模拟IPv6协议栈完成IPv6的解封装(调用ip6ip_ecn_decapsulate()函数)后,40ver6虚接口会将报文转交给内核(调用netif_rx(skb)函数),由内核IPv4协议栈处理后转交给上层应用。图8为4over6虚接口解封装收包过程示意图。
3 4over6驱动程序测试
3.1 测试准备
本文选择Linux Ubuntu 10.04作为开发环境,通过arm-eabi完成Android系统4over6驱动程序的交叉编译。此外,本文使用Samsung Galaxy Nexus作为实验机,通过Android软件开发工具包SD✞K(softwareDevelopment Kit)中的adb程序作为与实验机进行通信的接口工具,对4over6驱动程序进行控制与测试。
对于使用到netfilter的挂钩函数,需要在代码中对挂钩函数进行注册。注册流入方向DHCP报文的解封装函数,其数据结构如下:
nfho_in.hook=hook_func_in;
nfho in.hooknum=NF 1NET PRE ROUTING:
在实验机中安装tcpdump for android,可以对实验机的网络通信进行监控,获取流通的报文数据并保存为截包工具wireshark支持查看的.pcap文件。
3.2 测试结果
在实验机上加载4over6驱动程序后,将实验机接入双栈环境,实验机网络接口状态如图9所示。wlan0为实验机的实际WiFi接口,而publie4over6为实验机上的4over6虚接口。为在wlan0接口上为全球可寻址IPv6地址2402:f000:1:4410:a841:cb60:c04:49e;public40ver6接口上为部署在4over6 BR端的DHCP服务器分配的全球公网IPv4地址58.205.200.7。
通过adb从实验机中获取tcpdump抓包文件。图10所示为从抓包文件中观察到的DHCPv4-over-IPv6报文交互情况。可以看到,所有DHCP消息均通过IPv6协议进行传输。实验机通过该过程,从DHCP服务器处获得IP地址58.205.200.7、网关IP地址58.205.200.1等IPv4地址及相关配置。
通过实验机上Android默认浏览器访问www.google.com.hk。以对www.google.com.hk的DNS查询报文为例,tcpdump抓取的IPv4-in-IPv6报文内部结构如图11所示。可以看到,IPv4的DNS查询报文被封装为IPv4-in-IPv6报文。IP层头✯部(源IPv4地址为58.205.200.7,目的IPv4地址为58.205.200.1)的外部封装上了IPv6头部(源IPv6地址为2402:f000:1:4410:a841:eb60:c04:49e,目的IPv6地址为2001:da8:20d:27:7a2b:cbff:felb:6ce0)。说明4over6 en de module内核模块在加载后成功运行。
4 结论
4over6隧道过渡技术通过IPv6报文承载IPv4流量,使IPv6网络中的用户能穿越IPv6网络访问IPv4网络中的应用与服务,确保了IPv6过渡期间终端用户的网络体验。本文在Android系统中实现了以4over6过渡技术为基础的网络驱动程序,并通过实验验证了该驱动程序的可用性。希望本论文能为IPv6过渡技术研究人员与开发者提供参考。