linux内核 netlink,Linux 内核态与用户态通信 netlink

参考资料:

https://blog.csdn.net/zqixiao_09/article/details/77131283

155888990_1_20190308105204535.png

#include

#include

#include

#include

#include

#include

#include

#include

#define NETLINK_USER 22

#define USER_MSG (NETLINK_USER 1)

#define USER_PORT 50

MODULE_LICENSE("GPL");

MODULE_AUTHOR("arvik");

MODULE_DESCRIPTION("netlink_demo");

static void test_netlink_rcv(struct sk_buff *skb);

struct netlink_kernel_cfg cfg = {

.input = test_netlink_rcv,

/*...*/

};

static struct sock *test_netlink_sock = NULL;

int send_msg(int8_t *pbuf, uint16_t len)

{

struct sk_buff *nl_skb;

struct nlmsghdr *nlh;

int ret;

nl_skb = nlmsg_new(len, GFP_ATOMIC);

if (!nl_skb) {

printk("netlink_alloc_skb error\n");

return -1;

}

/*将header填充到skb中*/

nlh = nlmsg_put(nl_skb, 0, 0, USER_MSG, len, 0);

if (nlh == NULL) {

printk("put error\n");

nlmsg_free(nl_skb);

return -1;

}

/*拷贝data*/

memcpy(nlmsg_data(nlh), pbuf, len);

/*发送*/

ret = netlink_unicast(test_netlink_sock, nl_skb, USER_PORT, MSG_DONTWAIT);

return ret;

}

static void test_netlink_rcv(struct sk_buff *skb)

{

struct nlmsghdr *nlh = NULL;

void *data = NULL;

printk("skb->len %u\n", skb->len);

if (skb->len >= nlmsg_total_size(0))

{

nlh = nlmsg_hdr(skb);

data = NLMSG_DATA(nlh);

if (data) {

printk("kernel receive date : %s\n", (int8_t *)data);

send_msg(data, nlmsg_len(nlh));

}

}

}

static int __init test_netlink_init(void)

{

printk("test netlink init\n");

test_netlink_sock = netlink_kernel_create(&init_net, USER_MSG, &cfg);

if (test_netlink_sock == NULL) {

printk("test netlink init error\n");

return -1;

}

printk("test netlink init ok\n");

return 0;

}

static void __exit test_netlink_exit(void)

{

netlink_kernel_release(test_netlink_sock);

test_netlink_sock = NULL;

printk("test netlink exit\n");

}

module_init(test_netlink_init);

module_exit(test_netlink_exit);

#include

#include

#include

#include

#include

#include

#include

#include

#define NETLINK_USER 22

#define USER_MSG (NETLINK_USER 1)

#define MSG_LEN 100

#define MAX_PLOAD 100

struct _my_msg {

struct nlmsghdr hdr;

int8_t data[MSG_LEN];

};

int main()

{

char *data = "hello kernel";

socklen_t addr_len;

struct sockaddr_nl local, dest_addr;

int skfd;

struct nlmsghdr *nlh = NULL;

struct _my_msg info;

int ret;

//创建socket

skfd = socket(AF_NETLINK, SOCK_RAW, USER_MSG);

if (skfd == (-1)) {

fprintf(stderr, "create socket error...%s\n", strerror(errno));

return (-1);

}

/*绑定*/

memset(&local, 0, sizeof(local));

local.nl_family = AF_NETLINK;

local.nl_pid = 50;

local.nl_groups = 0;

if (bind(skfd, (struct sockaddr *)&local, sizeof(local)) != 0) {

fprintf(stderr, "bind error\n");

close(skfd);

return (-1);

}

//初始化目的地址

memset(&dest_addr, 0, sizeof(dest_addr));

dest_addr.nl_family = AF_NETLINK;

dest_addr.nl_pid = 0;

dest_addr.nl_groups = 0;

/*填写data*/

nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PLOAD));

memset(nlh, 0, sizeof(struct nlmsghdr));

nlh->nlmsg_len = NLMSG_SPACE(MAX_PLOAD);

nlh->nlmsg_flags = 0;

nlh->nlmsg_type = 0;

nlh->nlmsg_seq = 0;

nlh->nlmsg_pid = local.nl_pid;

memcpy(NLMSG_DATA(nlh), data, strlen(data));

ret = sendto(skfd, nlh, nlh->nlmsg_len, 0, (struct sockaddr *)&dest_addr, sizeof(struct sockaddr_nl));

if (ret < 0) {

// fprintf(stderr, "sendto error\n");

perror("sendto error: ");

close(skfd);

return (-1);

}

printf("wait kernel msg!\n");

memset(&info, 0, sizeof(info));

/*接受信息*/

ret = recvfrom(skfd, &info, sizeof(struct _my_msg), 0, (struct sockaddr *)&dest_addr, &addr_len);

if (ret <= 0) {

// fprintf(stderr, "recv from kernel error\n");

perror("recv from kernel error: ");

close(skfd);

return (-1);

}

printf("msg receive from kernel : %s\n", info.data);

close(skfd);

free((void *)nlh);

close(skfd);

return 0;

}

来源:http://www.icode9.com/content-3-134001.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值