本來是不打算寫這種基礎性的東西的,但是有很多同志經常問我(有同事也有網友)。所以就寫一下吧,這個是理解LINUX內核網絡子系統的基礎,ip conntrack等都是依賴這些基礎的。好的,閑話不多說了。來正文。
其實netfilter就是依靠一個全局的二維數組nf_hooks[][].可以把這個玩意看成一個8*32的矩陣。矩陣的每個成員就是一個雙向鏈表節點。看看,又是雙向鏈表,內核中雙向鏈表的地位真的太重要了。以雙向鏈表做骨架串起nf_hook_ops這個結構體。然后在運行時在掛HOOK的地方調用nf_iterate這個函數(叫的高深一點就叫迭代器,面試的時候我喜歡叫迭代器裝B嚇唬人^_^)依次從鏈表上取下nf_hook_ops中注冊的函數并執行。下面先給出一個圖。
然后HOOKS分別掛在五個地方,這五個地方分別對應著nf_hooks[NPROTO][NF_MAX_HOOKS]中NF_MAX_HOOKS的成員。
在內核中用宏來實現的(其實用一個枚舉來實現會更優雅一些):
/* IP Hooks */
/* After promisc drops, checksum checks. */
#define NF_IP_PRE_ROUTING0
/* If the packet is destined for this box. */
#define NF_IP_LOCAL_IN1
/* If the packet is destined for another interface. */
#define NF_IP_FORWARD2
/* Packets coming from a local process. */
#define NF_IP_LOCAL_OUT3
/* Packets about to hit the wire. */
#define NF_IP_POST_ROUTING4
#define NF_IP_NUMHOOKS5
這就是整個netfilter的基礎骨架,所有IP包都是經過這五個鉤子來處理的。
下面給出整體的框圖:
接下來最后一個細節了:
那就是nf_hook_ops函數返回值的潛規則:
#define NF_DROP 0
#define NF_ACCEPT 1
#define NF_STOLEN 2
#define NF_QUEUE 3
#define NF_REPEAT 4
#define NF_STOP 5
#define NF_MAX_VERDICT NF_STOP
netfilter框架就認這幾個返回值了。如果不按照規矩來的話,出了問題就別怪人家了。就像你去商店買東西一樣,你如果拿人民幣出來,人家愿意接受,你拿美元,如果老板是個行家也會接受,你如果拿冥鈔的話,老板會發火的,所以你首先要摸清楚老板的脾氣,不要拿冥鈔,這個道理是很淺顯的,所以同樣,按照人家的規矩來給返回值也是很淺顯的,照做就行了。
下面介紹一下這幾個返回值的意思:
NF_DROP 就是把這個包扔掉,不要了,對應的SKB也會被釋放。
NF_ACCEPT 這個包是我想要的,留下,繼續往下跑。
NF_STOLEN 不做任何處理,SKB也不會釋放,所以同志們要注意了,如果自已要玩高級點的一定要摸清楚再玩,半生不熟的就玩的話很容易出問題的。
NF_QUEUE 扔進SKB的隊列里面,接下來就是往用戶空間扔啦。
NF_STOP 這個和NF_ACCEPT的意義是一致的,但有一點區別,NF_ACCEPT接收到包后會繼續往后面扔,就是會往下一個HOOK點扔,但NF_STOP就不會繼續跑后面的HOOK點了。
就這么多了。很簡單吧。
更多文章、技術交流、商務合作、聯系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號聯系: 360901061
您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點擊下面給點支持吧,站長非常感激您!手機微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對您有幫助就好】元
