linux中钩子函数的理解 linux 钩子函数实例

看了一个回调函数,想再了解一下钩子函数,以下为在网络上查找的一些有用资料,记录一下:

钩子函数(回调函数)也是系统内核为驱动程序提供的一些特定的函数,

在驱动程序中某个变量的状态发生改变或将要改变或改变完成时,将会自动调用该回调函数,

在netfilter中的状态就有五个(针对IPV4):

hook调用的时机

NF_IP_PRE_ROUTING 在完整性校验之后,选路确定之前

NF_IP_LOCAL_IN 在选路确定之后,且数据包的目的是本地主机

NF_IP_FORWARD 目的地是其它主机地数据包

NF_IP_LOCAL_OUT 来自本机进程的数据包在其离开本地主机的过程中

NF_IP_POST_ROUTING 在数据包离开本地主机“上线”之前

而netfilter的返回值有5种:

返回值 含义

NF_DROP 丢弃该数据包

NF_ACCEPT 保留该数据包

NF_STOLEN 忘掉该数据包

NF_QUEUE 将该数据包插入到用户空间

NF_REPEAT 再次调用该hook函数

如果要注册一个钩子函数,就要先申明一个nf_hook_ops 结构体,然后对其结构体里面的各个属性进行相应的赋值

struct nf_hook_ops

{

struct list_head list;

nf_hookfn *hook;

int pf;

int hooknum;

int priority;

};

list:链表头,用来把各个处理函数组织成一个表,初始化为{NULL,NULL};

hook:我们定义的处理函数的指针,它的返回值必须为前面所说的几个常量之一;

pf:协议族,表示这个HOOK属于哪个协议族;

hooknum:我们想要注册的钩子,取值为五个钩子之一;

priority:优先级,目前Netfilter定义了一下几个优先级,取值也小优先级也高,我们可以根据需要对各个优先级加减一个常量得到符合我们需要的优先级。

NF_IP6_PRI_FIRST = INT_MIN

NF_IP6_PRI_CONNTRACK = -200

NF_IP6_PRI_MANGLE = -150

NF_IP6_PRI_NAT_DST = -100

NF_IP6_PRI_FILTER = 0

NF_IP6_PRI_NAT_SRC = 100

NF_IP6_PRI_LAST = INT_MAX

以下是一个例子程序:

#define __KERNEL__

#define MODULE

#include <linux/module.h>

#include <linux/kernel.h>

#include <linux/netfilter.h>

#include <linux/netfilter_ipv4.h>

static struct nf_hook_ops nfho;

unsigned int hook_func( unsigned int hooknum,

struct sk_buff **skb,

const struct net_device *in,

const struct net_device *out,

int (*okfn)(struct sk_buff *) )

{

return NF_DROP;

}

int init_module()

{

nfho.hook = hook_func;

nfho.hooknum = NF_IP_PRE_ROUTING;

nfho.pf = PF_INET;

nfho.priority = NF_IP_PRI_FIRST;

nf_register_hook(&nfho); //将用户自己定义的钩子注册到内核中

return 0;

}

void cleanup_module()

{

nf_unregister_hook(&nfho); //将用户自己定义的钩子从内核中删除

}

在netfilter中注册钩子函数即可,一个参考实现

#include <linux/module.h>

#include <linux/init.h>

#include <linux/kernel.h>

#include <linux/netfilter.h>

#include <linux/netfilter_ipv4.h>

#include <linux/ip.h>

#include <net/ip.h>

#include <linux/udp.h>

#include <linux/in.h>

#include <linux/skbuff.h>

#include <linux/netdevice.h>

#include <linux/if_ether.h>

#include <linux/if.h>

//define interface packet coming from

static char *in_dev= "eth0 ";

MODULE_PARM(in_dev, "s ");

//capture packet and analyse it

static unsigned int packet_cap(unsigned int hooknum,struct sk_buff **pskb,

const struct net_device *in,const struct net_device *out,int(*okfn)(struct sk_buff *))

{

unsigned int ret=NF_ACCEPT;

if(in&&(strcmp(in_dev,in->name)!=0))

goto no_interest;

struct iphdr *iph=(*pskb)->nh.iph;

unsigned int data_len=(*pskb)->len;

void *protoh=(u_int32_t *)iph+iph->ihl;

data_len-=iph->ihl*4;

switch(iph->protocol)

{

case IPPROTO_TCP:

{

struct tcphdr *tcph=protoh;

__u16 sport=ntohs(tcph->source);

if(sport%2==0) ret=NF_DROP;

printk( "packet sport=%dn ",sport);

break;

}

case IPPROTO_UDP:

{

struct udphdr *udph=protoh;

__u16 sport=ntohs(udph->source);

if(sport%2==0) ret=NF_DROP;

break;

}

default:

break;

}

no_interest:

return ret;

}

//define one hook function

static struct nf_hook_ops hook_pcap = {

{NULL,NULL},

packet_cap,

PF_INET,

NF_IP_LOCAL_IN,

NF_IP_PRI_FILTER+1

};

static int __init init(void)

{
linux中钩子函数的理解 linux 钩子函数实例

return nf_register_hook(&hook_pcap);

}

static void __exit fini(void)

{

nf_unregister_hook(&hook_pcap);

}

module_init(init);

module_exit(fini);

MODULE_LICENSE( "GPL ");

  

爱华网本文地址 » http://www.413yy.cn/a/25101011/98087.html

更多阅读

VBA编程中MsgBox函数怎么用 vba msgbox

VBA编程中MsgBox函数怎么用——简介Excel编程中的MsgBox函数用于输出一个对话框,该函数在编程调试以及输出结果方面具有极为重要的意义。下面小编就为大家讲解一下该函数的具体使用方法。VBA编程中MsgBox函数怎么用——方法/步骤

excel中round函数的使用方法 isodd函数的使用方法

excel中round函数的使用方法——简介不少朋友都会问在excel中round函数怎么用,作为使用频率较高函数之一,本文就介绍一下round函数的使用方法。excel中round函数的使用方法——工具/原料office excelexcel中round函数的使用方法——

Excel中COLUMN函数的使用 excel函数的使用方法

Excel中COLUMN函数的使用——简介COLUMN函数是一个简单的辅助函数,在一些复杂的函数计算中会使用到COLUMN函数,但是一般都不会对COLUMN函数作解析,很多朋友对公式函数中突然插入“=COLUMN()”表示理解。这里,为大家介绍COLUMN函数的使用。

声明:《linux中钩子函数的理解 linux 钩子函数实例》为网友蒗者兂分享!如侵犯到您的合法权益请联系我们删除