linux内核中怎样根据端口号获得与之对应sock
刚刚接触linux内核编程,在练习写一个netfilter的模块:通过local_in和local_out两个点来截取数据包,之后从数据包里面获取struct sock的指针。在local_out里面可以在sk_buff直接获取。但是,local_in就有麻烦了,sk_buff里面的sk成员因为还在ip层,没有填写(为NULL)。
试过:分协议,利用IP层以上的函数来查找。以TCP为例用inet_lookup函数获取,但是得到的还是null。
求解:有什么办法可以解决? 二楼附上代码:#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netfilter.h>
#include <linux/netfilter_ipv4.h>
#include <linux/skbuff.h>
#include <linux/tcp.h>
#include <linux/udp.h>
#include <net/tcp.h>
#include <net/inet_hashtables.h>
#include <linux/ip.h>
#include <linux/net.h>
#include <net/sock.h>
static struct nf_hook_ops nfno;
static struct nf_hook_ops nfno2;
static unsigned int my_hook_fun(unsigned int hooknum,
struct sk_buff **skb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr * iph = (*skb)->nh.iph;
struct tcphdr * tcph = (struct tcphdr *)((__u32*)iph+iph->ihl);
struct udphdr * udph = (struct udphdr *)((__u32*)iph+iph->ihl);
struct sock *sk;
if(hooknum == NF_IP_LOCAL_OUT)
{
printk("send a pack\n");
}
else
{
printk("recv a pack\n");
}
sk = (*skb)->sk;
if(iph->protocol == 6 )
{
printk("tcp,source port %d , dst port %d\n",ntohs(tcph->source),ntohs(tcph->dest));
if(sk==NULL)
{
sk = inet_lookup(&tcp_hashinfo,iph->saddr,tcph->source,iph->daddr,ntohs(tcph->dest),inet_iif(*skb));
}
}
else if(iph->protocol == 17)
{
printk("udp,source prot %d, dst prot %d\n",ntohs(udph->source),ntohs(udph->dest));
}
if(sk!=NULL && sk->sk_socket!=NULL)
printk("socket:%x \n",(unsigned int)(sk->sk_socket) );
else
{
if(sk==NULL)
{
printk("sk\n");
}
else
{
printk("socket\n");
}
}
return NF_ACCEPT;
}
static int __init drop_pack_ini(void)
{
nfno.hook = my_hook_fun;
nfno.hooknum = NF_IP_LOCAL_OUT;
nfno.pf = PF_INET;
nfno.priority = NF_IP_PRI_LAST;
nf_register_hook(&nfno);
nfno2.hook = my_hook_fun;
nfno2.hooknum = NF_IP_LOCAL_IN;
nfno2.pf = PF_INET;
nfno2.priority = NF_IP_PRI_LAST;
nf_register_hook(&nfno2);
return 0;
}
static voiddrop_pack_exe(void)
{
nf_unregister_hook(&nfno);
nf_unregister_hook(&nfno2);
}
module_init(drop_pack_ini);
module_exit(drop_pack_exe);
MODULE_LICENSE("GPL");
另外,我用的是2.6.18版本的linux内核源代码 问题已解决:
sk = inet_lookup(&tcp_hashinfo,iph->saddr,tcph->source,iph->daddr,ntohs(tcph->dest),inet_iif(*skb));
应改为:
sk = inet_lookup(&tcp_hashinfo,iph->saddr,tcph->source,iph->daddr,tcph->dest,inet_iif(*skb));
页:
[1]