Now,Let's Go!
使用的是Linux 2.6.19.1的内核代码。
首先是 在./Source/net/netfilter/core.c文件中的函数 nf_register_hook:
static DEFINE_SPINLOCK(nf_hook_lock);
int nf_register_hook(struct nf_hook_ops *reg)
{
struct list_head *i;
spin_lock_bh(&nf_hook_lock);
list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) {
if (reg->priority priority)
break;
}
list_add_rcu(®->list, i->prev);
spin_unlock_bh(&nf_hook_lock);
synchronize_net();
return 0;
}
EXPORT_SYMBOL(nf_register_hook);
void nf_unregister_hook(struct nf_hook_ops *reg)
{
spin_lock_bh(&nf_hook_lock);
list_del_rcu(®->list);
spin_unlock_bh(&nf_hook_lock);
synchronize_net();
}
EXPORT_SYMBOL(nf_unregister_hook);
int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n)
{
unsigned int i;
int err = 0;
for (i = 0; i 0)
nf_unregister_hooks(reg, i);
return err;
}
EXPORT_SYMBOL(nf_register_hooks);
void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n)
{
unsigned int i;
for (i = 0; i
上面分别是四个函数:
nf_register_hook,nf_unregister_hook,nf_register_hooks,nf_unregister_hooks.
功能是注册Hooks函数
输入的参数是struct nf_hook_ops *reg。
下面让我们看一个验证ARP报文的Hook代码,以表示我们如何使用Hook函数实现这种功能。
unsigned int arphook_snd(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in, const struct net_device *out,int (*okfn)(struct sk_buff*))
{
struct arphdr *arp;
struct net_device *dev;
unsigned char * arp_ptr;
unsigned char *sha, *tha;
u32 sip,tip;
unsigned short arpop;
unsigned int status=NF_DROP;
dev=(*skb)->dev;
arp = (*skb)->nh.arph;
arp_ptr= (unsigned char *)(arp 1);
sha = arp_ptr;
arp_ptr = dev->addr_len;
memcpy(&sip, arp_ptr, 4);
arp_ptr = 4;
tha = arp_ptr;
arp_ptr = dev->addr_len;
memcpy(&tip, arp_ptr, 4);
arpop=ntohs(arp->ar_op);
if(!check_ip(&tip,WABLOCK)) /*check block list*/
{
if(arpop==1) /*sending ARP request*/
{
if(!check_ip(&tip,WAARP)) /*if not in list add it*/
add_ip(&tip,WAARP);
}
status=NF_ACCEPT;
}
return(status);
}
下面是初始化一些参数的函数
static int arpstar_init(void)
{
arphkrcv.hook=arphook_rcv; /*arp receive hook*/
arphkrcv.hooknum=NF_ARP_IN;
arphkrcv.pf=NF_ARP;
arphkrcv.priority=NF_IP_PRI_FIRST;
nf_register_hook(&arphkrcv);
arphksnd.hook=arphook_snd; /*arp send hook*/
arphksnd.hooknum=NF_ARP_OUT;
arphksnd.pf=NF_ARP;
arphksnd.priority=NF_IP_PRI_FIRST;
nf_register_hook(&arphksnd);
iphkrcv.hook=iphook_rcv; /*ip rcv hook*/
iphkrcv.hooknum=NF_IP_LOCAL_IN;
iphkrcv.pf=PF_INET;
iphkrcv.priority=NF_IP_PRI_FIRST;
nf_register_hook(&iphkrcv);
tmac=strtomac(trustedmac);
trustip=strtou32(trustedip);
run_timer(0);
return(0);
}
下面是函数结束时候的清理工作
static void arpstar_exit(void)
{
nf_unregister_hook(&arphkrcv); /*clean up time*/
nf_unregister_hook(&arphksnd);
nf_unregister_hook(&iphkr
Linux下的网络HOOK实现以及使用方法【来自2.6.19内核】
2009年05月05日 星期二 下午 02:07
最近疯狂的研究Linux的种种功能,也颇有心得,这里讲述一下Linux下的Net的Hook,使用net的Hook可以实现很多很多非常底层的功能,比如过滤报文,做防火墙,做代理等等。 Now,Let's Go! 使用的是Linux 2.6.19.1的内核代码。 首先是 在./Source/net/netfilter/core.c文件中的函数 nf_register_hook: static DEFINE_SPINLOCK(nf_hook_lock); int nf_register_hook(struct nf_hook_ops *reg) { struct list_head *i; spin_lock_bh(&nf_hook_lock); list_for_each(i, &nf_hooks[reg->pf][reg->hooknum]) { if (reg->priority priority) break; } list_add_rcu(®->list, i->prev); spin_unlock_bh(&nf_hook_lock); synchronize_net(); return 0; } EXPORT_SYMBOL(nf_register_hook); void nf_unregister_hook(struct nf_hook_ops *reg) { spin_lock_bh(&nf_hook_lock); list_del_rcu(®->list); spin_unlock_bh(&nf_hook_lock); synchronize_net(); } EXPORT_SYMBOL(nf_unregister_hook); int nf_register_hooks(struct nf_hook_ops *reg, unsigned int n) { unsigned int i; int err = 0; for (i = 0; i 0) nf_unregister_hooks(reg, i); return err; } EXPORT_SYMBOL(nf_register_hooks); void nf_unregister_hooks(struct nf_hook_ops *reg, unsigned int n) { unsigned int i; for (i = 0; i 上面分别是四个函数: nf_register_hook,nf_unregister_hook,nf_register_hooks,nf_unregister_hooks. 功能是注册Hooks函数 输入的参数是struct nf_hook_ops *reg。 下面让我们看一个验证ARP报文的Hook代码,以表示我们如何使用Hook函数实现这种功能。 unsigned int arphook_snd(unsigned int hooknum,struct sk_buff **skb,const struct net_device *in, const struct net_device *out,int (*okfn)(struct sk_buff*)) { struct arphdr *arp; struct net_device *dev; unsigned char * arp_ptr; unsigned char *sha, *tha; u32 sip,tip; unsigned short arpop; unsigned int status=NF_DROP; dev=(*skb)->dev; arp = (*skb)->nh.arph; arp_ptr= (unsigned char *)(arp 1); sha = arp_ptr; arp_ptr = dev->addr_len; memcpy(&sip, arp_ptr, 4); arp_ptr = 4; tha = arp_ptr; arp_ptr = dev->addr_len; memcpy(&tip, arp_ptr, 4); arpop=ntohs(arp->ar_op); if(!check_ip(&tip,WABLOCK)) /*check block list*/ { if(arpop==1) /*sending ARP request*/ { if(!check_ip(&tip,WAARP)) /*if not in list add it*/ add_ip(&tip,WAARP); } status=NF_ACCEPT; } return(status); } 下面是初始化一些参数的函数 static int arpstar_init(void) { arphkrcv.hook=arphook_rcv; /*arp receive hook*/ arphkrcv.hooknum=NF_ARP_IN; arphkrcv.pf=NF_ARP; arphkrcv.priority=NF_IP_PRI_FIRST; nf_register_hook(&arphkrcv); arphksnd.hook=arphook_snd; /*arp send hook*/ arphksnd.hooknum=NF_ARP_OUT; arphksnd.pf=NF_ARP; arphksnd.priority=NF_IP_PRI_FIRST; nf_register_hook(&arphksnd); iphkrcv.hook=iphook_rcv; /*ip rcv hook*/ iphkrcv.hooknum=NF_IP_LOCAL_IN; iphkrcv.pf=PF_INET; iphkrcv.priority=NF_IP_PRI_FIRST; nf_register_hook(&iphkrcv); tmac=strtomac(trustedmac); trustip=strtou32(trustedip); run_timer(0); return(0); } 下面是函数结束时候的清理工作 static void arpstar_exit(void) { nf_unregister_hook(&arphkrcv); /*clean up time*/ nf_unregister_hook(&arphksnd); nf_unregister_hook(&iphkrcv); del_timer(&watimer); free_list(); kfree(tmac); } 我们知道Windows下面也有Hook的功能,但是要Hook到Net的底层,一般是使用NDIS来实现,但是Linux就提供了如此强大的功能,让我们不得不佩服Linux的伟大。几天的研究让我越来越对Linux的推崇!而且我想Linux在嵌入式方面的应用会更加广泛! 这几天也在看一些嵌入式的资料,想想,这个世界真的可以因为Linux的改变而改变,相对来说Windows的代码保密性会失去很多嵌入式方面的开发者的! |
del_timer(&watimer);
free_list();
kfree(tmac);
}
我们知道Windows下面也有Hook的功能,但是要Hook到Net的底层,一般是使用NDIS来实现,但是Linux就提供了如此强大的功能,让我们不得不佩服Linux的伟大。几天的研究让我越来越对Linux的推崇!而且我想Linux在嵌入式方面的应用会更加广泛!
这几天也在看一些嵌入式的资料,想想,这个世界真的可以因为Linux的改变而改变,相对来说Windows的代码保密性会失去很多嵌入式方面的开发者的!