说明请看这里http://www.ibm.com/developerworks/cn/linux/l-netlink/index.html
这里主要是贴在新的内核版本(3.2.0-29)能运行的代码。
imp2_k.c
1 #ifndef __KERNEL__ 2 #define __KERNEL__ 3 #endif 4 5 #ifndef MODULE 6 #define MODULE 7 #endif 8 9 #include <linux/module.h> 10 #include <linux/kernel.h> 11 #include <linux/init.h> 12 #include <linux/types.h> 13 #include <linux/netdevice.h> 14 #include <linux/skbuff.h> 15 #include <linux/netfilter_ipv4.h> 16 #include <linux/inet.h> 17 #include <linux/in.h> 18 #include <linux/ip.h> 19 #include <linux/netlink.h> 20 #include <linux/spinlock.h> 21 #include <linux/semaphore.h> 22 #include <net/sock.h> 23 #include "imp2.h" 24 25 struct semaphore receive_sem; 26 27 DEFINE_SEMAPHORE(receive_sem); 28 29 static struct sock *nlfd; 30 31 struct 32 { 33 __u32 pid; 34 rwlock_t lock; 35 }user_proc; 36 37 static void kernel_receive(struct sk_buff *skb) 38 { 39 struct nlmsghdr *nlh = NULL; 40 //printk("%s: skb->user: %d\n", __func__, atomic_read(&skb->users)); return; 41 42 43 44 if(down_trylock(&receive_sem)) 45 return; 46 47 if(skb->len < sizeof(struct nlmsghdr)) 48 goto out; 49 50 nlh = nlmsg_hdr(skb); 51 52 if((nlh->nlmsg_len >= sizeof(struct nlmsghdr)) 53 && (skb->len >= nlh->nlmsg_len)) { 54 if(nlh->nlmsg_type == IMP2_U_PID) { 55 write_lock_bh(&user_proc.lock); 56 user_proc.pid = nlh->nlmsg_pid; 57 write_unlock_bh(&user_proc.lock); 58 } else if(nlh->nlmsg_type == IMP2_CLOSE) { 59 write_lock_bh(&user_proc.lock); 60 if(nlh->nlmsg_pid == user_proc.pid) 61 user_proc.pid = 0; 62 write_unlock_bh(&user_proc.lock); 63 } 64 } 65 66 //kfree_skb(skb); 67 68 69 out: 70 up(&receive_sem); 71 } 72 73 static int send_to_user(struct packet_info *info) 74 { 75 int ret; 76 int size; 77 unsigned char *old_tail; 78 struct sk_buff *skb; 79 struct nlmsghdr *nlh; 80 struct packet_info *packet; 81 82 size = NLMSG_SPACE(sizeof(*info)); 83 84 skb = alloc_skb(size, GFP_ATOMIC); 85 old_tail = skb->tail; 86 87 nlh = NLMSG_PUT(skb, 0, 0, IMP2_K_MSG, size-sizeof(*nlh)); 88 packet = NLMSG_DATA(nlh); 89 memset(packet, 0, sizeof(struct packet_info)); 90 91 packet->src = info->src; 92 packet->dest = info->dest; 93 94 nlh->nlmsg_len = skb->tail - old_tail; 95 NETLINK_CB(skb).dst_group = 0; 96 97 read_lock_bh(&user_proc.lock); 98 ret = netlink_unicast(nlfd, skb, user_proc.pid, MSG_DONTWAIT); 99 read_unlock_bh(&user_proc.lock); 100 101 return ret; 102 103 nlmsg_failure: 104 if(skb) 105 kfree_skb(skb); 106 return -1; 107 } 108 109 static unsigned int get_icmp(unsigned int hook, 110 struct sk_buff *pskb, 111 const struct net_device *in, 112 const struct net_device *out, 113 int (*okfn)(struct sk_buff *)) 114 { 115 struct iphdr *iph = ip_hdr(pskb); 116 struct packet_info info; 117 118 if(iph->protocol == IPPROTO_ICMP) 119 { 120 printk("get a packet.\n"); 121 read_lock_bh(&user_proc.lock); 122 if(user_proc.pid != 0) 123 { 124 read_unlock_bh(&user_proc.lock); 125 info.src = iph->saddr; 126 info.dest = iph->daddr; 127 send_to_user(&info); 128 } 129 else 130 read_unlock_bh(&user_proc.lock); 131 } 132 133 return NF_ACCEPT; 134 } 135 136 static struct nf_hook_ops imp2_ops = 137 { 138 .hook = get_icmp, 139 .pf = PF_INET, 140 .hooknum = NF_INET_PRE_ROUTING, 141 .priority = NF_IP_PRI_FILTER -1, 142 }; 143 144 static int __init init(void) 145 { 146 rwlock_init(&user_proc.lock); 147 148 nlfd = netlink_kernel_create(&init_net, NL_IMP2, 0, kernel_receive, NULL,THIS_MODULE); 149 if(!nlfd) 150 { 151 printk("can not create a netlink socket\n"); 152 return -1; 153 } 154 155 return nf_register_hook(&imp2_ops); 156 } 157 158 static void __exit fini(void) 159 { 160 if(nlfd) 161 { 162 sock_release(nlfd->sk_socket); 163 } 164 nf_unregister_hook(&imp2_ops); 165 } 166 167 module_init(init); 168 module_exit(fini);