- 论坛徽章:
- 0
|
同志们,这个是我修改的论坛前辈的代码。操作系统是redhat5.0,内核是2.6.18。
现在的情况是:
代码在没有通讯的时候内核态程序正常,获得的user_proc.pid为0,
运行用户态代码,则死机。
代码如下:
头文件:
- #ifndef __IMP2_H__
- #define __IMP2_H__
- #define IMP2_U_PID 0
- #define IMP2_K_MSG 1
- #define IMP2_CLOSE 2
- #define NL_IMP2 31
- struct packet_info
- {
- __u32 src;
- __u32 dest;
- unsigned char protocol;
- unsigned short tot_len;
- };
- #endif
复制代码
内核态代码:
- #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;
- #if 0
- 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);
- 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);
- }
- #endif
- #if 1
- static void kernel_receive(struct sock *sk,int len)
- {
- struct sk_buff *skb = NULL;
- #if 1
- struct nlmsghdr *nlh = NULL;
- //printk("%s: skb->user: %d\n", __func__, atomic_read(&skb->users)); return;
- if(down_trylock(&receive_sem))
- return;
- if(skb->len < sizeof(struct nlmsghdr))
- goto out;
- // nlh = nlmsg_hdr(skb);
- nlh = (struct nlmsghdr *)skb->data;
- if((nlh->nlmsg_len >= sizeof(struct nlmsghdr))
- && (skb->len >= nlh->nlmsg_len))
- {
- printk("--------::::::::----------------");
- if(nlh->nlmsg_type == IMP2_U_PID)
- {
- write_lock_bh(&user_proc.lock);
- user_proc.pid = nlh->nlmsg_pid;
- printk("::::::user_proc.pid= %d\n",user_proc.pid);
- write_unlock_bh(&user_proc.lock);
- }
- else if(nlh->nlmsg_type == IMP2_CLOSE)
- {
- write_lock_bh(&user_proc.lock);
- if(nlh->nlmsg_pid == user_proc.pid)
- user_proc.pid = 0;
- write_unlock_bh(&user_proc.lock);
- }
- }
- //kfree_skb(skb);
- out:
- up(&receive_sem);
- #endif
- }
- #endif
- 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;
- packet->protocol = info->protocol;
- packet->tot_len = info->tot_len;
- nlh->nlmsg_len = skb->tail - old_tail;
-
- NETLINK_CB(skb).pid = 0;
- NETLINK_CB(skb).dst_group = 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 *))
- {
- printk("%s\n", __func__);
- //struct sk_buff *sb = *pskb;
- struct iphdr *ip = (*pskb)->nh.iph;
- struct packet_info info;
- //ip = sb->nh.iph;
- switch(ip->protocol)
- {
- case 89:
- printk("::OSPF::\n");
- break;
- case 1:
- printk("::ICMP::\n");
- break;
- case 2:
- printk("::IGMP::\n");
- break;
- case 6:
- printk("::TCP::\n");
- break;
- case 17:
- printk("::UDP::\n");
- break;
- }
- printk(" [ %d ]\n ",ip->tot_len );
-
- read_lock_bh(&user_proc.lock);
- printk("_____:::pid_2::%d\n",user_proc.pid );
- if(user_proc.pid != 0)
- {
- read_unlock_bh(&user_proc.lock);
- info.src = ip->saddr;
- info.dest = ip->daddr;
- info.tot_len = ip->tot_len;
- info.protocol = ip->protocol;
- printk("before send\n");
- send_to_user(&info);
- printk("after send\n");
- }
- else
- {
- read_unlock_bh(&user_proc.lock);
- }
-
- printk("-------------------send to user end-----------");
- 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_FIRST,
- };
- static int __init init(void)
- {
- rwlock_init(&user_proc.lock);
- //nlfd = netlink_kernel_create(NL_IMP2, kernel_receive);
- //nlfd = netlink_kernel_create(NL_IMP2, 0, 0,THIS_MODULE);
- printk("------------------------------------------------create----------\n");
- nlfd = netlink_kernel_create(NL_IMP2, 0, kernel_receive,THIS_MODULE);
- printk("---create----end------!!!\n");
- //nlfd = netlink_kernel_create(&init_net, NL_IMP2, 0, kernel_receive, NULL, THIS_MODULE);
- 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->sk_socket);
- }
- nf_unregister_hook(&imp2_ops);
- }
- module_init(init);
- module_exit(fini);
复制代码
用户态代码:
- #include <unistd.h>
- #include <stdio.h>
- #include <string.h>
- #include <sys/socket.h>
- #include <arpa/inet.h>
- #include <asm/types.h>
- #include <linux/netlink.h>
- #include <signal.h>
- #include "imp2.h"
- struct msg_to_kernel
- {
- struct nlmsghdr hdr;
- };
- struct u_packet_info
- {
- struct nlmsghdr hdr;
- struct packet_info icmp_info;
- };
- static int skfd;
- static void sig_int(int signo)
- {
- struct sockaddr_nl kpeer;
- struct msg_to_kernel message;
- memset(&kpeer, 0, sizeof(kpeer));
- kpeer.nl_family = AF_NETLINK;
- kpeer.nl_pid = 0;
- kpeer.nl_groups = 0;
- memset(&message, 0, sizeof(message));
- message.hdr.nlmsg_len = NLMSG_LENGTH(0);
- message.hdr.nlmsg_flags = 0;
- message.hdr.nlmsg_type = IMP2_CLOSE;
- message.hdr.nlmsg_pid = getpid();
- sendto(skfd, &message, message.hdr.nlmsg_len, 0, (struct sockaddr *)(&kpeer),sizeof(kpeer));
- close(skfd);
- exit(0);
- }
- int main(void)
- {
- struct sockaddr_nl local;
- struct sockaddr_nl kpeer;
- int kpeerlen;
- struct msg_to_kernel message;
- struct u_packet_info info;
- int sendlen = 0;
- int rcvlen = 0;
- struct in_addr addr;
- int count = 0;
- skfd = socket(PF_NETLINK, SOCK_RAW, NL_IMP2);
- if(skfd < 0)
- {
- printf("can not create a netlink socket\n");
- exit(0);
- }
- memset(&local, 0, sizeof(local));
- local.nl_family = AF_NETLINK;
- local.nl_pid = getpid();
- local.nl_groups = 0;
- if(bind(skfd, (struct sockaddr*)&local, sizeof(local)) != 0)
- {
- printf("bind() error\n");
- return -1;
- }
- #if 1
- signal(SIGINT, sig_int);
- memset(&kpeer, 0, sizeof(kpeer));
- kpeer.nl_family = AF_NETLINK;
- kpeer.nl_pid = 0;
- kpeer.nl_groups = 0;
- memset(&message, 0, sizeof(message));
- message.hdr.nlmsg_len = NLMSG_LENGTH(0);
- message.hdr.nlmsg_flags = 0;
- message.hdr.nlmsg_type = IMP2_U_PID;
- message.hdr.nlmsg_pid = local.nl_pid;
- sendto(skfd, &message, message.hdr.nlmsg_len, 0,
- (struct sockaddr*)&kpeer, sizeof(kpeer));
- #endif
- printf("RUN");
- while(1)
- {
- kpeerlen = sizeof(struct sockaddr_nl);
- rcvlen = recvfrom(skfd, &info, sizeof(struct u_packet_info),
- 0, (struct sockaddr*)&kpeer, &kpeerlen);
- if(rcvlen > 0)
- {
- ++count;
- }
- printf("------------------------------\n");
- printf("receive packet :: %d ",count);
- addr.s_addr = info.icmp_info.src;
- printf(" src: %s, ", inet_ntoa(addr));
- addr.s_addr = info.icmp_info.protocol;
- // printf(" Packet:%s",addr.s_addr);
- if(addr.s_addr == 6)
- {
- printf("TCP");
- }
- else if(addr.s_addr == 17)
- {
- printf("UDP");
- }
- else if(addr.s_addr == 1)
- {
- printf("ICMP");
- }
- else if(addr.s_addr == 2)
- {
- printf("IGMP");
- }
- else printf("unkown");
- addr.s_addr = info.icmp_info.dest;
- printf(" dest: %s\n", inet_ntoa(addr));
- addr.s_addr = info.icmp_info.tot_len;
- printf("::%d::",addr.s_addr);
- printf("-----------------------------\n");
-
- }
- return 0;
- }
复制代码
另,驱动程序的调试方法大家能给我指导下否?
相关的比较好的书籍或者帖子。
[ 本帖最后由 zengrui0342 于 2008-9-19 15:32 编辑 ] |
|