android linux kernel communicate with user space about NETLINK_USER

359 views Asked by At

I want to implements kernel communicate with user space,Here is my code:

        #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());
            .....

When I set NETLINK_USER = 17,18 or something else, then I exec this code :

    sock_fd = socket(PF_NETLINK, SOCK_RAW, NETLINK_USER); 

it show sock_fd return -1, so it must set NETLINK_USER = 16, I want know why? And I have another question: Here is my kernel code:

    #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);  

I found if I set NETLINK_USER = 16, when I insert kernel, the avd will stop running, but if I set NETLINK_USER = 31,28 or something else the avd will run normally,I want to know why it will like this? At last, I think the function hello_nl_recv_msg haven't exec, I don't know why.

0

There are 0 answers