天天看點

linux hook函數詳解,linux核心中的hook函數詳解

在編寫linux核心中的網絡子產品時,用到了鈎子函數也就是hook函數。現在來看看linux是如何實作hook函數的。

先介紹一個結構體:

struct nf_hook_ops,這個結構體是實作鈎子函數必須要用到的結構體,其實際的定義為:

linux hook函數詳解,linux核心中的hook函數詳解

其中的成員資訊為:

hook  :是一個函數指針,可以将自定義的函數指派給它,來實作當有資料包到達是調用你自定義的函數。自定義函數的傳回值為:

linux hook函數詳解,linux核心中的hook函數詳解

owner:是子產品的所有者,一般owner = THIS_MODULE ;

pf   :是protocol flags,其取值範圍為:

linux hook函數詳解,linux核心中的hook函數詳解

hooknum :中存放的是使用者自定義的鈎子函數的調用時機,其取值為:

linux hook函數詳解,linux核心中的hook函數詳解

其中的每個值的含義為:

linux hook函數詳解,linux核心中的hook函數詳解

priority : 為所定義的鈎子函數的優先級,其取值為份兩種:分别為IPV4 和 IPV6;

priority 的IPV4取值為:

linux hook函數詳解,linux核心中的hook函數詳解

priority 的IPV6取值為:

linux hook函數詳解,linux核心中的hook函數詳解

以上是對struct nf_hook_ops結構體中的每個字段的詳解;

現在舉例:

struct nf_hook_ops  my_hook = {

.hook = myfunction,

.owner = THIS_MODULE ,

.pf = NFPROTO_IPV4,

.hooknum = NET_INET_FORWARD ,

.priority = NF_IP4_PRI_FIRST };

unsigned int myfunction( unsigend int hooknum,  struct sk_buff *skb,

const struct net_device *in,

const struct net_device *out,

int (*okfn)(struct sk_buff *) )

{

}

如上面的代碼一樣,當定義一個struct nf_hook_ops結構體,并且對其完成了初始化以後,需要将這個結構體進行注冊,之後這個結構體以及其中的自定義函數才會其作用。

注冊一個struct nf_hook_ops需要用到的函數為:

int  nf_register_hook( struct nf_hook_ops *reg )

其實這個 int nf_register_hook()函數在核心中的實作也沒有多麼的複雜,

來看看它是如何實作的:

linux hook函數詳解,linux核心中的hook函數詳解

當不再需要使用這個struct nf_hook_ops時,需要登出這個結構體,其可用的函數為:

void nf_unregister_hook( struct nf_hook_ops *reg )

linux hook函數詳解,linux核心中的hook函數詳解

當一次需要注冊多個struct nf_hook_ops結構體,如:

struct nf_hook_ops myhooks[n]時,使用:

int nf_register_hooks( struct nf_hook_ops *regs, unsigned int n );

linux hook函數詳解,linux核心中的hook函數詳解

同樣,當一次需要登出多個struct nf_hook_ops結構體是,使用:

void nf_unregister_hoos( struct nf_hook_ops *regs, unsigned int n );

linux hook函數詳解,linux核心中的hook函數詳解

總結:

struct nf_hook_ops

int nf_register_hook( struct nf_hook_ops *reg );

void nf_unregister_hook( struct nf_hook_ops *reg );

int nf_register_hooks( struct nf_hook_ops *regs, unsigend int n );

void nf_unregister_hooks( struct nf_hook_ops *regs, unsigned int n );