当前位置: 技术问答>linux和unix
Linux 钩子模块的编写
来源: 互联网 发布时间:2015-10-28
本文导语: 公司有个项目,要求写个钩子模块,要求只允许VLAN1的请求通过,过滤掉其他的(公司内部的交换机采用VLAN),请问如何入手呀,有那些资料可以参考的呀 | 在netfilter中注册钩子函数即可,一...
公司有个项目,要求写个钩子模块,要求只允许VLAN1的请求通过,过滤掉其他的(公司内部的交换机采用VLAN),请问如何入手呀,有那些资料可以参考的呀
|
在netfilter中注册钩子函数即可,一个参考实现
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//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;
/*if((iph->frag_off)&IP_OFFSET)
break;
if(data_lensource);
if(sport%2==0) ret=NF_DROP;
printk("packet sport=%dn",sport);
break;
}
case IPPROTO_UDP: {
struct udphdr *udph=protoh;
/*if((iph->frag_off)&IP_OFFSET)
break;
if(data_lensource);
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");
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
//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;
/*if((iph->frag_off)&IP_OFFSET)
break;
if(data_lensource);
if(sport%2==0) ret=NF_DROP;
printk("packet sport=%dn",sport);
break;
}
case IPPROTO_UDP: {
struct udphdr *udph=protoh;
/*if((iph->frag_off)&IP_OFFSET)
break;
if(data_lensource);
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");
|
你需要在钩子函数里面来判断该数据包是否是指定的vlan所发出的包,进而可以控制是丢弃还是接收,这个是不难的,只要你知道如何判断是否是vlan发出的包就ok了
好运,好好理解一下吧。netfilter是很好用的一个框架
好运,好好理解一下吧。netfilter是很好用的一个框架
|
vlanid = (*(skb->data) & 0x0f) * 256 + *(skb->data + 1);
|
参照Netfilter,iptables ,你只用下钩子了。