我们了解了不少关于IPv6协议栈的知识,前文我们也提到了有关于(嵌入式精简IPv6协议栈)微型化IPv6协议栈的具体知识,现在我们就来把IPv6协议栈实现步骤呈现给大家。具体内容请参照下文。
IPv6协议栈设计与实现
在设计协议栈过程中,我们在嵌入式操作系统基础上设计和实现一个操作系统模拟层,实现基本的时钟,消息管理和进程同步等基本操作系统功能。协议进程方面,把所有的协议栈封装到单独进程中,应用程序可以驻留在其中或作为一个单独的进程,这样既实现了与操作系统分离,又避免了层间切换。对于内存管理采用类BSDbuf结构,把静态缓冲区和动态缓冲区链接起来。
IPv6协议
IPv6协议栈模块主要用于完成对接收到的IPv6数据报进行处理,对需要发送的IPv6数据包进行构造并递交底层发送。当接收到一个数据包时,网络设备驱动调用ip_input()函数来对其IP报头进行检查,检查其版本号,报文长度,载荷长度,目的节点地址和下一报头,待检查无误后,根据下一包头的类型分别提交给不同的处理模块。当要发送数据时,必须要知道发送报文的下一跳IPv6地址,以及该地址的相对应MAC地址,ip_route()函数就是为实现这样的功能而设计的,其获取下一跳IPv6地址与其对应MAC地址的处理流程,目的缓存用来存储着一系列最近的报文流量与对应的下一跳IP地址的关系,前缀列表存储着一系列子网前缀和其他地址前缀及其对应的下一跳IP地址的关系,如果两者中都没有找到匹配的记录,则再从前缀列表中选择默认路由器作为传输的下一跳IPv6地址。
在成功获取了下一跳IPv6协议地址后,数据就进入传输阶段,传输阶段由ip_outputif()函数控制,ip_output()函数填充好报头,选择好发送网络接口,然后激活发送网络接口进行数据发送。
ICMPV6
ICMPV6负责接收,解释和发送ICMPV6报文。收到报文后,如果为邻居信息报文则转交给邻居发现模块,如果为诊断报文则交给ICMPV6诊断模块。ICMPV6模块只实现了应答回复报文,目的不可达报文。当处理到达的IP报文时,如果下一报头既不是TCP,UDP也不是ICMPV6,那么表示在嵌入式设备端的协议栈的已经到达IP层,是端口不可达,发送目的不可达报文。当收到ICMPV6的应答请求报文时,就发送应答回复报文,其格式与请求报文相似,在收到的请求报文的基础上改变报文类型,重新计算校验和,在IP报头中将源,目的地址对调就可以了。
邻居发现
邻居发现是精简IPv6协议栈最核心的协议,它利用邻居请求报文和邻居公告报文的交换,实现地址解释,地址重复性检测,以及地址自动配置功能。不实现路由器请求/路由器公告报文,和重定向报文。
◆邻居请求报文
类型值为135,报文IP头的源地址域为发送邻居请求报文接口的地址或者未指定,目的地址域为与被请求目标地址相关联的被请求节点组播地址,或者就是被请求目标地址本身。ICMPV6报头域中的目标地址域为被请求目标地址。选项域可以包含源链路层地址选项,用来告诉对方发送请求节点的MAC地址,当源地址为指定地址时必须包含该选项。
◆邻居公告报文
类型值为136,用来响应邻居请求报文,或者用来告知节点其链路层地址的改变,报文IP头的源地址为发送邻居公告报文的接口地址,目的地址为发送邻居请求的单播地址,或者是用来公告给所有邻居节点其链路层地址改变的全节点多播地址。目标地址就是被解释的IPv6地址,或者在地址***性验证中将要采用的IPv6协议地址。地址解释就是节点仅仅知道邻居节点IP地址的情况下,通过发送邻居请求报文和接收邻居公告报文,来得到对应节点链路层地址的过程,是IPv6协议栈中邻居发现模块中最重要的一个功能模块。
节点A知道节点B的链路IPv6协议地址
FEC0:0:0:1::B但不知道节点B的链路层地址00-10-5C-F7-5C-96,沿箭头方向,A发送邻居请求报文,IP域的目的地址是要求被解释的目标地址FEC0:0:0:1::B。节点B收到邻居请求报文后,查看目标地址就是属于本机,是则发送一个单播的邻居公告报文给A,在邻居公告报文的目的链路层地址选项里包含节点B的链路层地址00-10-5C-F7-5C-96。这样节点A知道了节点B的链路层地址,地址解释过程完成。