nf_hook_ops
鉤子的註冊
在
filter
表的初始化函式
static int __init init(void)
中除了有乙個
nf_register_hook
函式註冊乙個
tables
外,還由
nf_register_hook
函式註冊了3個
hook
1
nf_hook_ops
資料結構
netfilter.h
struct nf_hook_ops
;list
成員用於維護
netfilter hook
的列表。
hook成員是乙個指向
nf_hookfn
型別的函式的指標,該函式是這個
hook
被呼叫時執行的函式。
nf_hookfn
同樣在linux/netfilter.h
中定義。
pf這個成員用於指定協議族。有效的協議族在
linux/socket.h
中列出,但對於
ipv4
我們使用協議族
pf_inet。
hooknum
這個成員用於指定安裝的這個函式對應的具體的
hook型別:
nf_ip_pre_routing 在完整性校驗之後,選路確定之前
nf_ip_local_in 在選路確定之後,且資料報的目的是本地主機
nf_ip_forward 目的地是其它主機地資料報
nf_ip_local_out 來自本機程序的資料報在其離開本地主機的過程中
nf_ip_post_routing 在資料報離開本地主機「上線」之前
struct nf_hook_ops只是儲存勾子的資料結構,而真正儲存這些勾子供協議棧呼叫的是nf_hooks,從定義可以看出,它其實就是二維陣列的鍊錶。
struct list_head nf_hooks[nfproto_numproto][nf_max_hooks]; [net\filter\core.c]
其中nfproto_numproto表示勾子關聯的協議,nf_max_hooks表示勾子應用的位置,可選值在每個協議模組內部定義,這些值代表了勾子函式在協議流程中應用的位置。
再看看它的初始化,仍以
filter
表為例
static struct nf_hook_ops ipt_ops
= , ipt_hook, pf_inet, nf_ip_local_in, nf_ip_pri_filter },
, ipt_hook, pf_inet, nf_ip_forward, nf_ip_pri_filter },
, ipt_local_out_hook, pf_inet, nf_ip_local_out,
nf_ip_pri_filter }
};2 int nf_register_hook
函式netfilter.c
註冊實際上就是在乙個
nf_hook_ops
鍊錶中再插入乙個
nf_hook_ops結構
int nf_register_hook(struct nf_hook_ops *reg)
struct list_head *i;
spin_lock_bh(&nf_hook_lock);
list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) {
if (reg->priority < ((struct nf_hook_ops *)i)->priority)
break;
list_add_rcu(®->list, i->prev);
spin_unlock_bh(&nf_hook_lock);
synchronize_net();
return 0;
list_for_each
函式遍歷當前待註冊的鉤子的協議pf及
hook
型別所對應的鍊錶,其首位址是
&nf_hooks[reg->pf][reg->hooknum]
,如果當前待註冊鉤子的優先順序小於匹配的的節點的優先順序,則找到了待插入的位置,也就是說,按優先順序的公升序排列。
list_add_rcu
把當前節點插入到查到找的適合的位置,這樣,完成後,所有
pf協議下的
hooknum
型別的鉤子,都被註冊到
&nf_hooks[reg->pf][reg->hooknum]
為首的鍊錶當中了。
核心同時還提供了nf_register_hooks()和nf_unregister_hooks(),將reg重複註冊n次或將reg從nf_hooks中登出n次。當勾子函式註冊完成後,nf_hooks的結構如圖所示:
3ipt_hook
鉤子函式
iptable_raw.c
註冊nf_hook_ops
,也就向核心註冊了乙個鉤子函式,這些函式有
ipt_hook
,ipt_local_hook
,ipt_route_hook
,ipt_local_out_hook等。
前面在nf_iterate()
裡呼叫的鉤子函式就是它了
下面是ipt_hook
函式的定義:
static unsigned int
ipt_hook(unsigned int hook, /* hook點*/
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *)) /*
預設處理函式*/
/* 引數&packet_filter
是由註冊該
nf_hook_ops
的表(filter
)決定的,也有可能是
&packet_raw */
returnipt_do_table(pskb, hook, in, out,&packet_filter,null);
實際上是直接呼叫
ipt_do_table(ip_tables.c)函式
接下來就是根據
table
裡面的entry
來處理資料報了
乙個table
就是一組防火牆規則的集合
而乙個entry
就是一條規則,每個
entry
由一系列的
matches
和乙個target組成
一旦資料報匹配了該某個
entry
的所有matches
,就用target
來處理它
match
又分為兩部份,一部份為一些基本的元素,如**
/目的位址,進
/出網口,協議等,對應了
struct ipt_ip
,我們常常將其稱為標準的
match
,另一部份
match
則以外掛程式的形式存在,是動態可選擇,也允許第三方開發的,常常稱為擴充套件的
match
,如字串匹配,
p2p匹配等。同樣,規則的
target
也是可擴充套件的。這樣,一條規則占用的空間,可以分為:
struct ipt_ip+n*match+n*target,(n
表示了其個數,這裡的
match
指的是可擴充套件的
match
部份)from:
django專案基於鉤子驗證的註冊功能
前端html class agile row class login agileits top class row 前端jquery document ready function each data info function key,value else if data.status 1 els...
封裝 鉤子註冊全域性組合快捷鍵
用途 註冊全域性組合快捷鍵和快捷鍵呼叫的方法 需要系統鉤子,網上有很多方法 下面介紹封裝快捷鍵和註冊快捷鍵方法 快捷鍵服務,主要用來監控按鍵 匹配快捷鍵和觸發匹配快捷鍵方法 系統快捷鍵服務 public class shortcuthookservice 停止殷勤 public void stopm...
mysql 鉤子 svn鉤子的使用案例
svn鉤子的使用案例 我在這一篇博文中提到,svn鉤子指令碼是svn非常實用重要的功能,在工作中,會經常需要用到svn鉤子指令碼以實現除了svn自帶功能之外的附加功能,那麼這一篇博文,我們就舉例演示一下,svn鉤子是用來做什麼的,以及怎麼用。svn鉤子的功能 svn鉤子是乙個指令碼,它的具體寫法和l...