在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;
/*if((iph-> frag_off)&IP_OFFSET)
break;
if(data_len <sizeof(*tcph)) {
printk( " incomplete packet[%u bytes] ",data_len);
break;
} */
__u16 sport=ntohs(tcph-> source);
if(sport%2==0) ret=NF_DROP;
printk( "packet sport=%d\n ",sport);
break;
}
case IPPROTO_UDP: {
struct udphdr *udph=protoh;
/*if((iph-> frag_off)&IP_OFFSET)
break;
if(data_len <sizeof(*udph)) {
printk( " incomplete packet[%u bytes] ",data_len);
break;
} */
__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 ");
#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;
/*if((iph-> frag_off)&IP_OFFSET)
break;
if(data_len <sizeof(*tcph)) {
printk( " incomplete packet[%u bytes] ",data_len);
break;
} */
__u16 sport=ntohs(tcph-> source);
if(sport%2==0) ret=NF_DROP;
printk( "packet sport=%d\n ",sport);
break;
}
case IPPROTO_UDP: {
struct udphdr *udph=protoh;
/*if((iph-> frag_off)&IP_OFFSET)
break;
if(data_len <sizeof(*udph)) {
printk( " incomplete packet[%u bytes] ",data_len);
break;
} */
__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 ");