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)
{
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 ");
更多阅读
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函数的使用。
matlab中subplot函数在画图中的应用 matlab中subplot函数
matlab 中subplot函数在画图中的应用如下:subplot(3,2,1)plot(x)title('默认格式')subplot(3,2,2)plot(x)set(gca,'xtick',[1 3 6 8]);set(gca,'ytick',[]);title('X自定义间隔,Y关闭')subplot(3,2,3)plot(x)
linux系统中scp命令的用法Permission denied排错二例 cd permission denied
已有 3393 次阅读 2011-05-07 15:53 标签:linuxscpPermissiondeniedlinux系统中scp命令的用法注意:在使用过程中如果出现 -bash: scp: command not found请执行yum install openssh-clientsscp是 secure copy的缩写, scp是linux系统