摘要:本文簡要介紹了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-),男,江蘇太倉人,講師,本科,研究方向為計算機網絡。