Who can give me the latest netlink programming samples?

后端 未结 2 1458
悲哀的现实
悲哀的现实 2020-12-15 03:00

I\'m writing a Linux driver using netlink to communicate between user space and kernel space. But I can\'t find some useful materials, because the netlink has changed from L

相关标签:
2条回答
  • 2020-12-15 03:22

    I have been away of kernel programming from some time now. So I can't give you a direct example on what changes have been introduced. I can tell you how I got to understand the netlink functions and how to use them, reading code. Especially code from NetworkManager or the wireless extensions (iwlib), since that was my area of focus 2 years ago. Those OSS projects always are on top on changes on the kernel and their code is not difficult to understand.

    0 讨论(0)
  • 2020-12-15 03:36

    The code below demonstrates the basics of sending data from a user space application to a kernel module using netlink. This code works on Linux 2.6.28.9 with the git version (ef8ba32) of libnl. For more details, check out the libnl documentation and the code for iw which extensively uses netlink.

    Kernel

    #include <linux/kernel.h>
    #include <linux/module.h>
    
    #include <net/sock.h>
    #include <net/netlink.h>
    
    #define MY_MSG_TYPE (0x10 + 2)  // + 2 is arbitrary. same value for kern/usr
    
    static struct sock *my_nl_sock;
    
    DEFINE_MUTEX(my_mutex);
    
    static int
    my_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh)
    {
        int type;
        char *data;
    
        type = nlh->nlmsg_type;
        if (type != MY_MSG_TYPE) {
            printk("%s: expect %#x got %#x\n", __func__, MY_MSG_TYPE, type);
            return -EINVAL;
        }
    
        data = NLMSG_DATA(nlh);
        printk("%s: %02x %02x %02x %02x %02x %02x %02x %02x\n", __func__,
                data[0], data[1], data[2], data[3],
                data[4], data[5], data[6], data[7]);
        return 0;
    }
    
    static void
    my_nl_rcv_msg(struct sk_buff *skb)
    {
        mutex_lock(&my_mutex);
        netlink_rcv_skb(skb, &my_rcv_msg);
        mutex_unlock(&my_mutex);
    }
    
    static int
    my_init(void)
    {
        my_nl_sock = netlink_kernel_create(&init_net, NETLINK_USERSOCK, 0,
                my_nl_rcv_msg, NULL, THIS_MODULE);
        if (!my_nl_sock) {
            printk(KERN_ERR "%s: receive handler registration failed\n", __func__);
            return -ENOMEM;
        }
    
        return 0;
    }
    
    static void
    my_exit(void)
    {
        if (my_nl_sock) {
            netlink_kernel_release(my_nl_sock);
        }
    }
    
    module_init(my_init);
    module_exit(my_exit);
    

    User Space

    #include <stdio.h>
    #include <stdlib.h>
    
    #include <netlink/netlink.h>
    
    #define MY_MSG_TYPE (0x10 + 2)  // + 2 is arbitrary but is the same for kern/usr
    int
    main(int argc, char *argv[])
    {
        struct nl_sock *nls;
        char msg[] = { 0xde, 0xad, 0xbe, 0xef, 0x90, 0x0d, 0xbe, 0xef };
        int ret;
    
        nls = nl_socket_alloc();
        if (!nls) {
            printf("bad nl_socket_alloc\n");
            return EXIT_FAILURE;
        }
    
        ret = nl_connect(nls, NETLINK_USERSOCK);
        if (ret < 0) {
            nl_perror(ret, "nl_connect");
            nl_socket_free(nls);
            return EXIT_FAILURE;
        }
    
        ret = nl_send_simple(nls, MY_MSG_TYPE, 0, msg, sizeof(msg));
        if (ret < 0) {
            nl_perror(ret, "nl_send_simple");
            nl_close(nls);
            nl_socket_free(nls);
            return EXIT_FAILURE;
        } else {
            printf("sent %d bytes\n", ret);
        }
    
        nl_close(nls);
        nl_socket_free(nls);
    
        return EXIT_SUCCESS;
    }
    
    0 讨论(0)
提交回复
热议问题