论文部分内容阅读
摘要:本文简要介绍了IPv6数据包处理流程,重点阐述了嵌入式IPv6的核心协议:IPv6协议、ICMPv6协议和邻居发现协议的设计与实现。
关键词:IPv6;ICMPv6;邻居发现协议
中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)06-00ppp-0c
The Design and Implementation of Embedded IPv6 Stack
LI Zhi-gang
(Chien-shiung Institute of Technology the Department of Information Engineering,Suzhou 215400,China)
Abstract:This paper introduced the data technological process of IPv6,and placed its importance on the design and implementation of IPv6 core Protocol:IPv6,ICMPv6,Neighbor discovery.
Key words:IPv6;ICMPv6;Neighbor discovery
随着嵌入式Internet技术的迅猛发展,在嵌入式操作系统中集成TCP/IP协议,使嵌入式设备能够连接Internet,己经成为嵌入式系统发展的重要方向。目前,嵌入式Internet系统主要应用于IPv4网络,但随着互联网规模的不断扩大,尤其在大量的嵌入式网络设备接人Internet网络后,IPv4的问题就逐渐暴露出来:32bit的IP地址空间的匾乏、越来越庞大的路由表、复杂的地址配置、缺乏QoS(Quality of Service)的支持、安全性问题等,严重制约了嵌入式Internet技术的发展。作为下一代网络协议IPv6协议具有128位的IP地址空间、较小的路由表、即插即用的配置、QoS的支持和内建的安全性等,可以更好地满足嵌入式系统对联网功能的需求,在嵌入式系统中实现IPv6
协议有着良好的应用前景。基于这样的背景,着手研究嵌入式IPv6协议栈的设计与实现,具有重要的现实意义。
1 数据处理流程
正确处理数据流程是实现IPv6协议栈设计的基础。图1显示了对收到IPv6数据包和发送IPv6数据包的处理流程。
图1 IPv6数据包处理流程
接收数据时,网络接口层将从网卡接收到的数据存到缓冲区,通过读取数据的以太帧报头,根据以太帧报头的类型字段判断以太类型,若以太类型等于0x86DD,则为IPv6数据包,把IPv6数据包发送给协议栈输入处理模块。输入处理模块先做合法性检测,若不合法就抛弃,同时向源地址发送的差错报文,若合法的话, 根据下一报头的值调用不同的处理函数。
发送数据时,应用程序用UDP或TCP方式发送,按UDP或TCP报文格式封装数据包,然后把数据包传输到IP层,首先要选择下一跳IP地址,根据下一跳IP地址值先搜索存储最近通信信息的目的缓存表以获得对应的MAC地址,若目的缓存表中正好存储所需的下一跳IP地址,则取出对应的MAC地址,填充MAC地址和报头,然后调用IPv6输出函数,发送数据包;若目的缓存表查找失败,即没有所需的信息,则要在邻居缓存表查找,如果邻居缓存中没有对应的物理地址,则发送邻居请求报文,同时将待发送的包放到等待队列中。否则调用IPv6输出函数,直接发送数据包就可以了。
2 IPv6模块设计
IPv6模块主要包括两部分的功能,一是负责从网络接口层收取IPv6数据包,对数据包进行一定的处理后将包发送给不同的处理模块(TCP , UDP或ICMPv6 )。二是从上层接收数据,进行报文的选路,封装IPv6报头后将数据报发送给网络接口层。
2.1 主要数据结构设计
本系统设计的嵌入式IPv6协议栈只支持基本的IPv6报头,而不支持其他扩展选项。因此设计时与IPv4最大的不同集中在地址长度上。
IPv6的地址结构定义为:
struct ip_addr {
uint32 addr[4];
};
IPv6头部结构定义为:
typedef struct{
uint8vhlPrio;/*高四位为6,低四位为0 */
uint8Prioflow; /* 默认值为0*/
uint16flow; /*默认值为0*/
uint16payload; /* 有效载荷长度*/
uint8next;/*TCP为6,UDP为17,ICMPv6为58*/
uint8HopLimit;/* 128 */
struct ip_addrsrc;/* 源IP地址 */
struct ip_addrdest;/*目的IP地址 */
} IPHDR6;
2.2 主要函数设计
在IPv6函数设计中,本文所要实现接收数据包处理和发送数据包处理。
2.2.1 接收数据包函数:IPv6_input(ipv6_buf*buf)
当网络设备接收到数据时,以消息的形式发送给TCP/IP线程。TCP/IP线程中的接收函数判断出包的类型为IPv6包,则调用IPv6模块的输入函数对其进行处理。输入函数检测接收数据报文的合法性,将报文传递给下一模块。报文合法性的判断包括检查IP包的版本号是否为6,判断是否是本机的单播地址,是否是相应的组播地址,计算校验和是否为0,检查IPv6头部中的下一头部是否为ICMPv6、TCP或UDP,如果检测的条件中有一个不符合,就会丢弃该报文。对于符合接收条件的报文,应根据IPv6报头中“下一头部”的值,作相应的处理:若“下一头部”值等于17,则交给UDP输入处理,若“下一头部”值等于6,则交给TCP输入处理,若“下一头部”等于58,则交给ICMPv6输入处理。
2.2.2 发送报文函数:IPv6_output(ipv6_buf*buf)
当发送数据时,首先填充以太帧头部和IPv6头部,首先在目的缓存表中查找下一跳IP地址对应的MAC地址,若查找失败,则在邻居缓存表中查找下一跳的IP地址,若在邻居缓存表中查找失败,则把待发送报文放到等待队列,同时发送邻居请求报文以获得对应的下一跳IP地址的物理地址。若查找成功,则填充相应的以太帧头部和IPv6头部,计算出校验和,调用底层发送函数,实现IPv6数据包的发送。
3 ICMPv6模块的设计
ICMPv6是IPv6体系结构总体的一个组成。ICMPv6具备了IPv4中的ICMP所有基本功能,并且抛弃了一些不再使用的过时消息类型,提供了一些简化功能。ICMPv6负责接收、解释、发送ICMPv6报文。本设计主要实现了ICMPv6的echo应答,以及报错信息中的目的不可达。
3.1 主要数据结构设计
ICMPv6回声请求回声应答结构定义为:
typedef struct{
uint8 type; /*类型,回声请求128 回声应答 129 */
uint8 icode; /*编码,置0*/
uint16 chksum; /*校验和字段,计算方法和UDP校验和计算方法类似*/
uint16 id; /*标识, 应答报文应和请求报文相同*/
uint16 seqno; /*序号,应答报文应和请求报文相同*/
uint8icmp6data[32]; /*数据域*/
}icmp6_echo;
ICMPv6目的不可到达消息结构定义为:
typedef struct{
uint8 type; /* 类型 */
uint8 icode; /*编码*/
uint16 chksum; /* 校验和字段,计算方法和UDP校验和计算方法类似 */
uint32 unused; /* 保留*/
uint8icmp6data[32]; /* 数据域*/
}icmp6_dur;
3.2 主要函数设计
3.2.1 void icmp6_input(icmp6_buf*buf)
icmp6_input函数由IPv6_input()函数调用,其功能是处理接收到的ICMPv6报文,处理过程如下:构造IPv6伪报头,然后判断校验和是否有效,如果无效,丢弃该ICMPv6报文;否则,根据“类型字段”值做出响应的处理:如果“类型字段”的值为128, 则ICMPv6报文是Request报文,按照Reply格式封装数据包格式,并调用icmp6_output发送;如果类型字段的值为134,则ICMPv6报文是路由公告报文,调用ipv6_rt_adv函数处理;如果类型字段的值为135,则ICMPv6报文是邻居请求报文,按照邻居宣告格式封装报文,调用ipv6_nb_req函数;如果类型字段的值为136,ICMPv6报文是邻居宣告报文,则更新邻居缓存表,同时检查等待队列,若等待队列中有报文并且报文的IP地址等于刚接受到的邻居宣告报文中的源IP地址,则用刚收到的MAC填充报文,调用ipv6_nb_adv函数;其他情况,丢弃该ICMPv6报文。
3.2.2 void icmp6_output(icmp6_buf*buf)
icmp6_output函数的功能是为将要发送的ICMPv6报文添加ICMPv6基本报头,构造出IPv6伪报头,计算出ICMPv6校验和并且调用ip6_snd函数发送ICMPv6报文。
4 邻居发现模块的设计
IPv6协议中一个重要特征就是IPv6的邻居发现协议,该协议用于地址解析,邻居发现以及路由器及网络参数发现。基本代替了原来IPv4协议中的ARP协议,路由发现协议等。有5种不同的邻居发现报文:路由器请求报文、路由器公告报文、邻居请求报文、邻居公告报文和重定向报文。邻居发现报文选项提供了附加的信息,这些信息用于表示Mac地址、链路上网络前缀、链路上的MTU信息、重定向数据、移动信息和特定的路由。
本设计中只实现了路由器公告报文、邻居请求报文、邻居公告报文,通过这三个报文的交互可以使源节点和目的节点的MAC地址和IPv6地址进行绑定并且保存在对方的地址缓存区中。
4.1 主要数据结构设计
邻居请求报文宣告报文数据结构为:
typedef struct NBFind
{uint8Type; /*类型:请求135,宣告136*/
uint8Code; /*编码:0*/
uint16 Checksum; /*校验和*/
uint32 Reserved; /*保留位*/
struct ip_addr TgAddress;/*目标地址*/
uint8Ctype;/*选项类型*/
uint8Length;/*长度*/
uint8MACAddress[6]; /*物理地址*/
} NBDISCOVERRY;
4.2 主要函数设计
4.2.1 void ipv6_rt_adv(ipv6_buf*buf)
ipv6_rt_adv函数的功能是接收路由公告报文,提取出报文中的路由前缀,并且更新路由前缀缓冲表和重新本机IPv6地址。最后将addr_flag设置成ADDR_INET。
4.2.2 void ipv6_nb_req(ipv6_buf*buf)
ipv6_nb_req函数的功能是接收邻居请求报文,生成邻居公告报文并在邻居公告报文中加入本机的IPv6地址和MAC地址。最后调用icmp6_output函数发送ICMPv6报文。
4.2.3 void ipv6_nb_adv (ipv6_buf*buf)
ipv6_nb_adv函数的功能是接收邻居公告报文,如果addr_flag的值为ADDR_INET|ADDR LNK提取出报文中的信源的IPv6地址和MAC地址更新邻居缓冲表。如果addr_flag的状态是ADDR_CHK,将addr_flaa的值设置为ADDR_UNUSE。
5 小结
本文在现有的开源LwIP协议栈基础上实现了IPv6协议,整个系统代码编译后占用空间小,能够适合大部分嵌入式系统的要求。并且系统ARM μC/OS-II实时操作系统上通过测试, 证明了本方案的基本系统是可行的。
参考文献:
[1]R Braden.RFC 1633 Integrated Services in the Internet Architecture: an Overview[S].
[2]陈赜,刘振兴,李宗福,等.ARM嵌入式技术实践教程[M].北京航空航天大学出版社,2005.
[3]杜春蕾.ARM体系结构与编程[M].清华大学出版社,2003.
[4]吴永航.嵌入式Internet方案的设计与实现[D].大连理工大学,2003.
收稿日期:2008-01-10
作者简介:李志刚(1971-),男,江苏太仓人,讲师,本科,研究方向为计算机网络。
关键词:IPv6;ICMPv6;邻居发现协议
中图分类号:TP393文献标识码:A文章编号:1009-3044(2008)06-00ppp-0c
The Design and Implementation of Embedded IPv6 Stack
LI Zhi-gang
(Chien-shiung Institute of Technology the Department of Information Engineering,Suzhou 215400,China)
Abstract:This paper introduced the data technological process of IPv6,and placed its importance on the design and implementation of IPv6 core Protocol:IPv6,ICMPv6,Neighbor discovery.
Key words:IPv6;ICMPv6;Neighbor discovery
随着嵌入式Internet技术的迅猛发展,在嵌入式操作系统中集成TCP/IP协议,使嵌入式设备能够连接Internet,己经成为嵌入式系统发展的重要方向。目前,嵌入式Internet系统主要应用于IPv4网络,但随着互联网规模的不断扩大,尤其在大量的嵌入式网络设备接人Internet网络后,IPv4的问题就逐渐暴露出来:32bit的IP地址空间的匾乏、越来越庞大的路由表、复杂的地址配置、缺乏QoS(Quality of Service)的支持、安全性问题等,严重制约了嵌入式Internet技术的发展。作为下一代网络协议IPv6协议具有128位的IP地址空间、较小的路由表、即插即用的配置、QoS的支持和内建的安全性等,可以更好地满足嵌入式系统对联网功能的需求,在嵌入式系统中实现IPv6
协议有着良好的应用前景。基于这样的背景,着手研究嵌入式IPv6协议栈的设计与实现,具有重要的现实意义。
1 数据处理流程
正确处理数据流程是实现IPv6协议栈设计的基础。图1显示了对收到IPv6数据包和发送IPv6数据包的处理流程。
图1 IPv6数据包处理流程
接收数据时,网络接口层将从网卡接收到的数据存到缓冲区,通过读取数据的以太帧报头,根据以太帧报头的类型字段判断以太类型,若以太类型等于0x86DD,则为IPv6数据包,把IPv6数据包发送给协议栈输入处理模块。输入处理模块先做合法性检测,若不合法就抛弃,同时向源地址发送的差错报文,若合法的话, 根据下一报头的值调用不同的处理函数。
发送数据时,应用程序用UDP或TCP方式发送,按UDP或TCP报文格式封装数据包,然后把数据包传输到IP层,首先要选择下一跳IP地址,根据下一跳IP地址值先搜索存储最近通信信息的目的缓存表以获得对应的MAC地址,若目的缓存表中正好存储所需的下一跳IP地址,则取出对应的MAC地址,填充MAC地址和报头,然后调用IPv6输出函数,发送数据包;若目的缓存表查找失败,即没有所需的信息,则要在邻居缓存表查找,如果邻居缓存中没有对应的物理地址,则发送邻居请求报文,同时将待发送的包放到等待队列中。否则调用IPv6输出函数,直接发送数据包就可以了。
2 IPv6模块设计
IPv6模块主要包括两部分的功能,一是负责从网络接口层收取IPv6数据包,对数据包进行一定的处理后将包发送给不同的处理模块(TCP , UDP或ICMPv6 )。二是从上层接收数据,进行报文的选路,封装IPv6报头后将数据报发送给网络接口层。
2.1 主要数据结构设计
本系统设计的嵌入式IPv6协议栈只支持基本的IPv6报头,而不支持其他扩展选项。因此设计时与IPv4最大的不同集中在地址长度上。
IPv6的地址结构定义为:
struct ip_addr {
uint32 addr[4];
};
IPv6头部结构定义为:
typedef struct{
uint8vhlPrio;/*高四位为6,低四位为0 */
uint8Prioflow; /* 默认值为0*/
uint16flow; /*默认值为0*/
uint16payload; /* 有效载荷长度*/
uint8next;/*TCP为6,UDP为17,ICMPv6为58*/
uint8HopLimit;/* 128 */
struct ip_addrsrc;/* 源IP地址 */
struct ip_addrdest;/*目的IP地址 */
} IPHDR6;
2.2 主要函数设计
在IPv6函数设计中,本文所要实现接收数据包处理和发送数据包处理。
2.2.1 接收数据包函数:IPv6_input(ipv6_buf*buf)
当网络设备接收到数据时,以消息的形式发送给TCP/IP线程。TCP/IP线程中的接收函数判断出包的类型为IPv6包,则调用IPv6模块的输入函数对其进行处理。输入函数检测接收数据报文的合法性,将报文传递给下一模块。报文合法性的判断包括检查IP包的版本号是否为6,判断是否是本机的单播地址,是否是相应的组播地址,计算校验和是否为0,检查IPv6头部中的下一头部是否为ICMPv6、TCP或UDP,如果检测的条件中有一个不符合,就会丢弃该报文。对于符合接收条件的报文,应根据IPv6报头中“下一头部”的值,作相应的处理:若“下一头部”值等于17,则交给UDP输入处理,若“下一头部”值等于6,则交给TCP输入处理,若“下一头部”等于58,则交给ICMPv6输入处理。
2.2.2 发送报文函数:IPv6_output(ipv6_buf*buf)
当发送数据时,首先填充以太帧头部和IPv6头部,首先在目的缓存表中查找下一跳IP地址对应的MAC地址,若查找失败,则在邻居缓存表中查找下一跳的IP地址,若在邻居缓存表中查找失败,则把待发送报文放到等待队列,同时发送邻居请求报文以获得对应的下一跳IP地址的物理地址。若查找成功,则填充相应的以太帧头部和IPv6头部,计算出校验和,调用底层发送函数,实现IPv6数据包的发送。
3 ICMPv6模块的设计
ICMPv6是IPv6体系结构总体的一个组成。ICMPv6具备了IPv4中的ICMP所有基本功能,并且抛弃了一些不再使用的过时消息类型,提供了一些简化功能。ICMPv6负责接收、解释、发送ICMPv6报文。本设计主要实现了ICMPv6的echo应答,以及报错信息中的目的不可达。
3.1 主要数据结构设计
ICMPv6回声请求回声应答结构定义为:
typedef struct{
uint8 type; /*类型,回声请求128 回声应答 129 */
uint8 icode; /*编码,置0*/
uint16 chksum; /*校验和字段,计算方法和UDP校验和计算方法类似*/
uint16 id; /*标识, 应答报文应和请求报文相同*/
uint16 seqno; /*序号,应答报文应和请求报文相同*/
uint8icmp6data[32]; /*数据域*/
}icmp6_echo;
ICMPv6目的不可到达消息结构定义为:
typedef struct{
uint8 type; /* 类型 */
uint8 icode; /*编码*/
uint16 chksum; /* 校验和字段,计算方法和UDP校验和计算方法类似 */
uint32 unused; /* 保留*/
uint8icmp6data[32]; /* 数据域*/
}icmp6_dur;
3.2 主要函数设计
3.2.1 void icmp6_input(icmp6_buf*buf)
icmp6_input函数由IPv6_input()函数调用,其功能是处理接收到的ICMPv6报文,处理过程如下:构造IPv6伪报头,然后判断校验和是否有效,如果无效,丢弃该ICMPv6报文;否则,根据“类型字段”值做出响应的处理:如果“类型字段”的值为128, 则ICMPv6报文是Request报文,按照Reply格式封装数据包格式,并调用icmp6_output发送;如果类型字段的值为134,则ICMPv6报文是路由公告报文,调用ipv6_rt_adv函数处理;如果类型字段的值为135,则ICMPv6报文是邻居请求报文,按照邻居宣告格式封装报文,调用ipv6_nb_req函数;如果类型字段的值为136,ICMPv6报文是邻居宣告报文,则更新邻居缓存表,同时检查等待队列,若等待队列中有报文并且报文的IP地址等于刚接受到的邻居宣告报文中的源IP地址,则用刚收到的MAC填充报文,调用ipv6_nb_adv函数;其他情况,丢弃该ICMPv6报文。
3.2.2 void icmp6_output(icmp6_buf*buf)
icmp6_output函数的功能是为将要发送的ICMPv6报文添加ICMPv6基本报头,构造出IPv6伪报头,计算出ICMPv6校验和并且调用ip6_snd函数发送ICMPv6报文。
4 邻居发现模块的设计
IPv6协议中一个重要特征就是IPv6的邻居发现协议,该协议用于地址解析,邻居发现以及路由器及网络参数发现。基本代替了原来IPv4协议中的ARP协议,路由发现协议等。有5种不同的邻居发现报文:路由器请求报文、路由器公告报文、邻居请求报文、邻居公告报文和重定向报文。邻居发现报文选项提供了附加的信息,这些信息用于表示Mac地址、链路上网络前缀、链路上的MTU信息、重定向数据、移动信息和特定的路由。
本设计中只实现了路由器公告报文、邻居请求报文、邻居公告报文,通过这三个报文的交互可以使源节点和目的节点的MAC地址和IPv6地址进行绑定并且保存在对方的地址缓存区中。
4.1 主要数据结构设计
邻居请求报文宣告报文数据结构为:
typedef struct NBFind
{uint8Type; /*类型:请求135,宣告136*/
uint8Code; /*编码:0*/
uint16 Checksum; /*校验和*/
uint32 Reserved; /*保留位*/
struct ip_addr TgAddress;/*目标地址*/
uint8Ctype;/*选项类型*/
uint8Length;/*长度*/
uint8MACAddress[6]; /*物理地址*/
} NBDISCOVERRY;
4.2 主要函数设计
4.2.1 void ipv6_rt_adv(ipv6_buf*buf)
ipv6_rt_adv函数的功能是接收路由公告报文,提取出报文中的路由前缀,并且更新路由前缀缓冲表和重新本机IPv6地址。最后将addr_flag设置成ADDR_INET。
4.2.2 void ipv6_nb_req(ipv6_buf*buf)
ipv6_nb_req函数的功能是接收邻居请求报文,生成邻居公告报文并在邻居公告报文中加入本机的IPv6地址和MAC地址。最后调用icmp6_output函数发送ICMPv6报文。
4.2.3 void ipv6_nb_adv (ipv6_buf*buf)
ipv6_nb_adv函数的功能是接收邻居公告报文,如果addr_flag的值为ADDR_INET|ADDR LNK提取出报文中的信源的IPv6地址和MAC地址更新邻居缓冲表。如果addr_flag的状态是ADDR_CHK,将addr_flaa的值设置为ADDR_UNUSE。
5 小结
本文在现有的开源LwIP协议栈基础上实现了IPv6协议,整个系统代码编译后占用空间小,能够适合大部分嵌入式系统的要求。并且系统ARM μC/OS-II实时操作系统上通过测试, 证明了本方案的基本系统是可行的。
参考文献:
[1]R Braden.RFC 1633 Integrated Services in the Internet Architecture: an Overview[S].
[2]陈赜,刘振兴,李宗福,等.ARM嵌入式技术实践教程[M].北京航空航天大学出版社,2005.
[3]杜春蕾.ARM体系结构与编程[M].清华大学出版社,2003.
[4]吴永航.嵌入式Internet方案的设计与实现[D].大连理工大学,2003.
收稿日期:2008-01-10
作者简介:李志刚(1971-),男,江苏太仓人,讲师,本科,研究方向为计算机网络。