免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 2190 | 回复: 1
打印 上一主题 下一主题

关于独孤九贱的一个netlink例子中的锁的问题?求高手解决 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2007-12-25 10:49 |只看该作者 |倒序浏览
#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包的时候,机器会死掉?请问问题出在什么地方?

论坛徽章:
0
2 [报告]
发表于 2007-12-25 13:01 |只看该作者
应该有报错信息的吧?
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP