?
最近瘋狂的研究Linux的種種功能,也頗有心得,這里講述一下Linux下的Net的Hook,使用net的Hook可以實現(xiàn)很多很多非常底層的功能,比如過濾報文,做防火墻,做代理等等。
Now,Let's Go!
使用的是Linux 2.6.19.1的內(nèi)核代碼。
首先是 在./Source/net/netfilter/core.c文件中的函數(shù) 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 < ((struct nf_hook_ops *)i)->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 < n; i++) {
err = nf_register_hook(?[i]);
if (err)
goto err;
}
return err;
err:
if (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 < n; i++)
nf_unregister_hook(?[i]);
}
EXPORT_SYMBOL(nf_unregister_hooks);
上面分別是四個函數(shù):
nf_register_hook,nf_unregister_hook,nf_register_hooks,nf_unregister_hooks.
功能是注冊Hooks函數(shù)
輸入的參數(shù)是struct nf_hook_ops *reg。
下面讓我們看一個驗證ARP報文的Hook代碼,以表示我們?nèi)绾问褂肏ook函數(shù)實現(xiàn)這種功能。
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);
}
下面是初始化一些參數(shù)的函數(shù)
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);
}
下面是函數(shù)結(jié)束時候的清理工作
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來實現(xiàn),但是Linux就提供了如此強(qiáng)大的功能,讓我們不得不佩服Linux的偉大。幾天的研究讓我越來越對Linux的推崇!而且我想Linux在嵌入式方面的應(yīng)用會更加廣泛!
這幾天也在看一些嵌入式的資料,想想,這個世界真的可以因為Linux的改變而改變,相對來說Windows的代碼保密性會失去很多嵌入式方面的開發(fā)者的!
評論
查看更多