Linux2 6下ESP包解析流程

2021-06-27 15:13:19 字數 2701 閱讀 1364

1. 前言

在linux2.6中自帶了ipsec的實現,可以不再使用freeswan及其變種了,freeswan通過建立ipsec*的

虛擬網絡卡來將傳送和接收ipsec資料報,通過ipsec*網絡卡看到的資料是明文資料,而2.6中的ipsec實

現是不建立ipsec*虛擬網絡卡的,本文分析一下esp包進入系統協議棧的處理流程。

以下linux核心**版本為2.6.19.2。

2. 流程分析

2.1 esp協議結構

esp協議結構定義,對於每個ipv4上層的協議,如tcp、udp、icmp、igmp、esp、ah等都需要定義這個

結構掛接到ipv4的協議鍊錶中,當接收到ip資料報時,會根據包中定義的ip協議號找到該結構,然後

呼叫其成員handler函式進行處理。

/* net/ipv4/esp4.c */

static struct net_protocol esp4_protocol = ;

esp協議的handler函式是xfrm4_rcv()

2.2 xfrm4_rcv

/* net/ipv4/xfrm4_input.c */

int xfrm4_rcv(struct sk_buff *skb)

實際就是xfrm4_rcv_encap,封裝型別引數設定為0,即沒封裝資料

2.3 xfrm4_rcv_encap

/* net/ipv4/xfrm4_input.c */

int xfrm4_rcv_encap(struct sk_buff *skb, __u16 encap_type)

// 看內層協議是否還要繼續解包, 不需要解時返回1, 需要解時返回0, 錯誤返回負數

// 協議型別可以多層封裝的,比如用ah封裝esp, 就得先解完ah再解esp

if ((err = xfrm_parse_spi(skb, skb->nh.iph->protocol, &spi, &seq)) < 0)

goto drop;

} while (!err);

/* allocate new secpath or cow existing one. */

// 為skb包建立新的安全路徑(struct sec_path)

if (!skb->sp || atomic_read(&skb->sp->refcnt) != 1)

if (xfrm_nr + skb->sp->len > xfrm_max_depth)

goto drop;

// 將剛才迴圈解包用到的sa拷貝到安全路徑

// 因此檢查乙個資料報是否是普通明文包還是解密後的明文包就看skb->sp引數是否為空

memcpy(skb->sp->xvec + skb->sp->len, xfrm_vec,

xfrm_nr * sizeof(xfrm_vec[0]));

skb->sp->len += xfrm_nr;

nf_reset(skb);

if (decaps)

// 重新進入網絡卡接收函式

netif_rx(skb);

return 0;

} else

drop_unlock:

spin_unlock(&x->lock);

xfrm_state_put(x);

drop:

while (--xfrm_nr >= 0)

xfrm_state_put(xfrm_vec[xfrm_nr]);

kfree_skb(skb);

return 0;

}最後說一下返回負協議值的處理, ip上層協議的handler是在ip_local_deliver_finish()函式中呼叫

的:/* net/ipv4/ip_input.c */

static inline int ip_local_deliver_finish(struct sk_buff *skb)

nf_reset(skb);

}// 呼叫協議handler

ret = ipprot->handler(skb);

if (ret < 0)

ip_inc_stats_bh(ipstats_mib_indelivers);

} else

} else

ip_inc_stats_bh(ipstats_mib_indelivers);

kfree_skb(skb);}}

out:

rcu_read_unlock();

return 0;

}3. 結論

雖然在2.6的native ipsec中沒支援虛擬網絡卡,但在通道模式下也用到了netif_rx函式將解碼後的數

據包重新接收處理的過程,並沒有改變skb包的dev網絡卡引數,因此如果在該網絡卡上抓包,就會同時抓

到最初的加密包和解碼後的明文包;而用freeswan的實現,在普通網絡卡上抓包抓到的是加密包,由於

freeswan在解碼後將skb包的dev引數改為了ipsec*,因此是通過在ipsec*網絡卡上能抓到解密包。對於

傳輸模式,由於沒有呼叫netif_rx函式,因此在實際網絡卡抓包只能抓到加密包,解密包只能在

netfilter架構中看到了。

另外,在此情況下nat規則仍然是有效的,制定nat規則時根據解密後的位址埠等資訊來處理就可以

了。識別乙個明文包是否是解密過的就看skb的sp引數即可,該指標為空表示是普通明文包,非空表示是

解密後的明文包。

Linux2 6 核心的 Initrd 機制解析

1 什麼是 initrd initrd 的英文含義是 boot loader initialized ram disk,就是由 boot loader 初始化的記憶體盤。在 linux核心啟動前,boot loader 會將儲存介質中的 initrd 檔案載入到記憶體,核心啟動時會在訪問真正的根檔案...

Linux2 6 核心的 Initrd 機制解析

initrd 的英文含義是 boot loader initialized ram disk,就是由 boot loader 初始化的記憶體盤。在 linux核心啟動前,boot loader 會將儲存介質中的 initrd 檔案載入到記憶體,核心啟動時會在訪問真正的根檔案系統前先訪問該記憶體中的 ...

Linux2 6下如何配置core檔案

1.可以用ulimit a 檢視一下棧的大小。在核心2.6.20下,stack size 為8192 kbytes 如果這裡沒有限制,就棧的大小就只受記憶體的限制。2g是上限。2.core 檔案 開啟或關閉core檔案的生成 ulimit c 可以檢視是否開啟此選項,若為0則為關閉 ulimit c...