- 论坛徽章:
- 0
|
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/types.h>
#include <linux/netdevice.h>
#include <linux/skbuff.h>
#include <linux/netfilter_ipv4.h>
#include <linux/inet.h>
#include <linux/in.h>
#include <linux/ip.h>
#include <linux/netlink.h>
#include <linux/spinlock.h>
#include <asm/semaphore.h>
#include <net/sock.h>
#include "imp2.h"
DECLARE_MUTEX(receive_sem);
static struct sock *nlfd;
struct
{
__u32 pid;
rwlock_t lock;
}user_proc;
static void kernel_receive(struct sock *sk, int len)
{
do
{
struct sk_buff *skb;
if(down_trylock(&receive_sem))
return;
while((skb = skb_dequeue(&sk->receive_queue)) != NULL)
{
{
struct nlmsghdr *nlh = NULL;
if(skb->len >= sizeof(struct nlmsghdr))
{
nlh = (struct nlmsghdr *)skb->data;
if((nlh->nlmsg_len >= sizeof(struct nlmsghdr))
&& (skb->len >= nlh->nlmsg_len))
{
if(nlh->nlmsg_type == IMP2_U_PID)
{
write_lock_bh(&user_proc.pid);
user_proc.pid = nlh->nlmsg_pid;
write_unlock_bh(&user_proc.pid);
}
else if(nlh->nlmsg_type == IMP2_CLOSE)
{
write_lock_bh(&user_proc.pid);
if(nlh->nlmsg_pid == user_proc.pid)
user_proc.pid = 0;
write_unlock_bh(&user_proc.pid);
}
}
}
}
kfree_skb(skb);
}
up(&receive_sem);
}while(nlfd && nlfd->receive_queue.qlen);
}
static int send_to_user(struct packet_info *info)
{
int ret;
int size;
unsigned char *old_tail;
struct sk_buff *skb;
struct nlmsghdr *nlh;
struct packet_info *packet;
size = NLMSG_SPACE(sizeof(*info));
skb = alloc_skb(size, GFP_ATOMIC);
old_tail = skb->tail;
nlh = NLMSG_PUT(skb, 0, 0, IMP2_K_MSG, size-sizeof(*nlh));
packet = NLMSG_DATA(nlh);
memset(packet, 0, sizeof(struct packet_info));
packet->src = info->src;
packet->dest = info->dest;
nlh->nlmsg_len = skb->tail - old_tail;
NETLINK_CB(skb).dst_groups = 0;
read_lock_bh(&user_proc.lock);
ret = netlink_unicast(nlfd, skb, user_proc.pid, MSG_DONTWAIT);
read_unlock_bh(&user_proc.lock);
return ret;
nlmsg_failure:
if(skb)
kfree_skb(skb);
return -1;
}
static unsigned int get_icmp(unsigned int hook,
struct sk_buff **pskb,
const struct net_device *in,
const struct net_device *out,
int (*okfn)(struct sk_buff *))
{
struct iphdr *iph = (*pskb)->nh.iph;
struct packet_info info;
if(iph->protocol == IPPROTO_ICMP)
{
read_lock_bh(&user_proc.lock);
if(user_proc.pid != 0)
{
read_unlock_bh(&user_proc.lock);
info.src = iph->saddr;
info.dest = iph->daddr;
send_to_user(&info);
}
else
read_unlock_bh(&user_proc.lock);
}
return NF_ACCEPT;
}
static struct nf_hook_ops imp2_ops =
{
.hook = get_icmp,
.pf = PF_INET,
.hooknum = NF_IP_PRE_ROUTING,
.priority = NF_IP_PRI_FILTER -1,
};
static int __init init(void)
{
rwlock_init(&user_proc.lock);
nlfd = netlink_kernel_create(NL_IMP2, kernel_receive);
if(!nlfd)
{
printk("can not create a netlink socket\n");
return -1;
}
return nf_register_hook(&imp2_ops);
}
static void __exit fini(void)
{
if(nlfd)
{
sock_release(nlfd->socket);
}
nf_unregister_hook(&imp2_ops);
}
module_init(init);
module_exit(fini);
以上代码在 smp机器中编译后,开启用户接受程序,在机器一直接受ping包的时候,机器会死掉?请问问题出在什么地方? |
|