netlink代码示例

在用户和内核通信过程中,netlink非常方便,优势如下:

1,双向

2,异步

3,多播

代码如下:

内核模块net_link.c代码:

#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/types.h>
#include <linux/sched.h>
#include <net/sock.h>
#include <net/netlink.h>

#define NETLINK_TEST 21

struct sock *nl_sk = NULL;
EXPORT_SYMBOL_GPL(nl_sk);

void nl_data_ready (struct sk_buff *__skb)
{
        struct sk_buff *skb;
        struct nlmsghdr *nlh;
        u32 pid;
        int rc;
        int len = NLMSG_SPACE(1200);
        char str[100];

        printk("net_link: data is ready to read.\n");
        skb = skb_get(__skb);

        if (skb->len >= NLMSG_SPACE(0)) {
                nlh = nlmsg_hdr(skb);
                printk("net_link: recv %s.\n", (char *)NLMSG_DATA(nlh));
                memcpy(str,NLMSG_DATA(nlh), sizeof(str));
                pid = nlh->nlmsg_pid; /*pid of sending process */
                printk("net_link: pid is %d\n", pid);
                kfree_skb(skb);

                skb = alloc_skb(len, GFP_ATOMIC);
                if (!skb){
                        printk(KERN_ERR "net_link: allocate failed.\n");
                        return;
                }
                nlh = nlmsg_put(skb,0,0,0,1200,0);
                NETLINK_CB(skb).pid = 0; /* from kernel */

                memcpy(NLMSG_DATA(nlh), str, sizeof(str));
                printk("net_link: going to send.\n");
                rc = netlink_unicast(nl_sk, skb, pid, MSG_DONTWAIT);
                if (rc < 0) {
                        printk(KERN_ERR "net_link: can not unicast skb (%d)\n", rc);
                }
                printk("net_link: send is ok.\n");
        }
        return;
}


static int test_netlink(void) {
        nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST, 0, nl_data_ready, NULL, THIS_MODULE);

        if (!nl_sk) {
                printk(KERN_ERR "net_link: Cannot create netlink socket.\n");
                return -EIO;
        }
        printk("net_link: create socket ok.\n");
        return 0;
}

int init_module()
{
        test_netlink();
        return 0;
}
void cleanup_module( )
{
        if (nl_sk != NULL){
                sock_release(nl_sk->sk_socket);
        }
        printk("net_link: remove ok.\n");
}
MODULE_LICENSE("GPL");
MODULE_AUTHOR("kidoln");

用户sender.c代码:

#include <sys/stat.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <string.h>
#include <asm/types.h>
#include <linux/netlink.h>
#include <linux/socket.h>

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

int main(int argc, char* argv[])
{
        sock_fd = socket(PF_NETLINK, SOCK_RAW, 21);
        memset(&msg, 0, sizeof(msg));
        memset(&src_addr, 0, sizeof(src_addr));
        src_addr.nl_family = AF_NETLINK;
        src_addr.nl_pid = getpid(); /* self pid */
        src_addr.nl_groups = 0; /* not in mcast groups */
        bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr));
        memset(&dest_addr, 0, sizeof(dest_addr));
        dest_addr.nl_family = AF_NETLINK;
        dest_addr.nl_pid = 0; /* For Linux Kernel */
        dest_addr.nl_groups = 0; /* unicast */

        nlh=(struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
        /* Fill the netlink message header */
        nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD);
        nlh->nlmsg_pid = getpid(); /* self pid */
        nlh->nlmsg_flags = 0;
        /* Fill in the netlink message payload */
        strcpy(NLMSG_DATA(nlh), "Hello you!");

        iov.iov_base = (void *)nlh;
        iov.iov_len = nlh->nlmsg_len;
        msg.msg_name = (void *)&dest_addr;
        msg.msg_namelen = sizeof(dest_addr);
        msg.msg_iov = &iov;
        msg.msg_iovlen = 1;

        printf(" Sending message. ...\n");
        sendmsg(sock_fd, &msg, 0);



        /* Read message from kernel */
        memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));
        printf(" Waiting message. ...\n");
        recvmsg(sock_fd, &msg, 0);
        printf(" Received message payload: %s\n",NLMSG_DATA(nlh));

        /* Close Netlink Socket */
        close(sock_fd);
}

Makefile文件代码:

MODULE_NAME :=net_link
obj-m :=$(MODULE_NAME).o
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
all:
        $(MAKE) -C $(KERNELDIR) M=$(PWD)
        gcc -o sender sender.c
clean:
        rm -fr *.ko *.o *.cmd sender $(MODULE_NAME).mod.c

具体代码示例,可以参考其他博客,这里只提供简单的实例,供编程参考之用。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值