android linux内核与用户空间进行有关NETLINK_USER的通信

时间:2015-06-09 07:21:00

标签: android linux-kernel

我想实现内核与用户空间的通信,这是我的代码:

        #include <sys/socket.h>
        #include <linux/netlink.h>
        #include <stddef.h>

        #define NETLINK_USER 16 
        #define MAX_PAYLOAD 1024 /* maximum payload size*/
        struct sockaddr_nl src_addr, dest_addr;
        struct nlmsghdr *nlh = NULL;
        struct iovec iov;
        int sock_fd;
        struct msghdr msg;

        void main()
        {
            sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER);  
            printf("%d\n",sock_fd);
            if (sock_fd < 0)
                return -1;

            memset(&src_addr, 0, sizeof(src_addr));
            src_addr.nl_family = AF_NETLINK;
            src_addr.nl_pid = getpid(); /* self pid */
            printf("%d\n",getpid());
            .....

当我设置NETLINK_USER = 17,18或其他内容时,我执行此代码:

    sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER); 

它显示sock_fd返回-1,所以它必须设置NETLINK_USER = 16,我想知道为什么? 我还有另一个问题:这是我的内核代码:

    #include <linux/kernel.h>
    #include <linux/module.h>
    #include <linux/moduleparam.h>
    #include <linux/unistd.h>
    #include <linux/semaphore.h>
    #include <asm/cacheflush.h>
    #include <linux/string.h>
    #include <net/sock.h>
    #include <linux/netlink.h>
    #include <linux/skbuff.h>
    #include <stddef.h>

    #define NETLINK_USER 16

    struct sock *nl_sk = NULL;

    void **sys_call_table;

    asmlinkage int (*original_call_open) (const char*, int, int);

    asmlinkage int (*original_call_read) (unsigned int, char*, int);

    asmlinkage long (*sys_openat) (int, const char*, int, int);

    asmlinkage long our_openat(int dfd, const char *filename, int flags, int mode){
        printk("%s\n",filename);
        return sys_openat(dfd,filename,flags,mode);
    }


     void hello_nl_recv_msg(struct sk_buff *skb)
    {

        struct nlmsghdr *nlh;
        int pid;
        struct sk_buff *skb_out;
        int msg_size;
        char *msg = "Hello from kernel";
        int res;

        printk(KERN_INFO "Entering: %s\n", __FUNCTION__);

        msg_size = strlen(msg);

        nlh = (struct nlmsghdr *)skb->data;
        printk(KERN_INFO "Netlink received msg payload:%s\n", (char *)nlmsg_data(nlh));
        pid = nlh->nlmsg_pid; //pid of sending process 

        skb_out = nlmsg_new(msg_size, 0);

        if (!skb_out)
        {

            printk(KERN_ERR "Failed to allocate new skb\n");
            return;

        }
        nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);
        NETLINK_CB(skb_out).dst_group = 0; //not in mcast group 
        strncpy(nlmsg_data(nlh), msg, msg_size);

        res = nlmsg_unicast(nl_sk, skb_out, pid);

        if (res < 0)
            printk(KERN_INFO "Error while sending bak to user\n");

    }



    int init_module()
    {

        printk("Entering: %s\n", __FUNCTION__);
        nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, 0, hello_nl_recv_msg, NULL, THIS_MODULE);
       // printk("%s",nl_sk);
       // nl_sk = netlink_kernel_create(NETLINK_USER, input);
        if (!nl_sk)
        {

            printk(KERN_ALERT "Error creating socket.\n");
            return -10;

        }

        return 0;
    }

    void cleanup_module()
    {
       // Restore the original call
       sys_call_table[__NR_open] = original_call_open;
       sys_call_table[__NR_read] = original_call_read;
       sys_call_table[__NR_openat] = sys_openat;
       printk(KERN_INFO "exiting hello module\n");
       netlink_kernel_release(nl_sk);
    }

    //MODULE_LICENSE("GPL");  
    //module_init(init_module);  
    //module_exit(cleanup_module);  

我发现如果我设置NETLINK_USER = 16,当我插入内核时,avd将停止运行,但如果我设置NETLINK_USER = 31,28或其他东西avd将正常运行,我想知道它为什么会这样? 最后,我认为函数hello_nl_recv_msg没有exec,我不知道为什么。

0 个答案:

没有答案