linux netlink 编程示例(一)内核端
生活随笔
收集整理的這篇文章主要介紹了
linux netlink 编程示例(一)内核端
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Netlink是一種內核層與應用層通信的一種機制,比如說在做一個內核模塊的時候,往往會需要應用層提供一些配置信息,這時候就可以使用netlink。netlink包括內核層和應用層,內核層注冊一個netlink協議,然后定義一些消息類型,之后就可以等待來自應用層的消息了。這篇博文給出一個簡單的netlink內核模塊使用例子,應用層會在接下來的博文中給出。
內核版本:3.4.39。 不同內核版本可能帶來編譯問題,可以升級內核來解決。升級3.4.39內核可以參考這一篇博客(https://blog.csdn.net/fuyuande/article/details/79429441)
netlink 內核端代碼如下:nlkernel.c
/**? Description : 內核netlink編程*? Date? ? ? ? :20180528*? Author? ? ? :mason*? Mail? ? ? ? : mrsonko@126.com**/ #include <linux/kernel.h> #include <linux/module.h> #include <linux/init.h> #include <linux/netlink.h> #include <linux/netfilter.h> #include <linux/netfilter_ipv4.h> #include <net/ip.h> #include "nlkernel.h"static int number; static struct sock *nlsock = NULL;? // netlink 套接字// netlink消息回復,用于向應用層傳遞數據 static void netlink_sendto_userapp(unsigned int dst_pid) {struct sk_buff *skb = NULL;struct nlmsghdr *nlh = NULL;int datalen;int *pnum;datalen = NLMSG_SPACE(sizeof(int));skb = alloc_skb(datalen, GFP_KERNEL);if(!skb){log("alloc skb error.\r\n");return ;}// 數據初始化nlh = nlmsg_put(skb, 0, 0, 0, sizeof(int), 0);nlh->nlmsg_pid = 0;nlh->nlmsg_type = NLKERNEL_GET;pnum = (int *)NLMSG_DATA(nlh);*pnum = number;? ??netlink_unicast(nlsock, skb, dst_pid, MSG_DONTWAIT);log("netlink send done \r\n");return;? ?? }/* netlink消息處理函數 */ static int netlink_kernel_rcv_msg(struct sk_buff *skb, struct nlmsghdr *nlh) {int *value = NULL;switch(nlh->nlmsg_type){// 設置case NLKERNEL_SET :log("kernel receive netlink set msg!\r\n");value = (int *)NLMSG_DATA(nlh);? ? ? ? ? ??number = *value;break;// 獲取case NLKERNEL_GET :log("kernel receive netlink get msg!\r\n");netlink_sendto_userapp(nlh->nlmsg_pid);break;default:log("unrecognized netlink message type : %u \r\n",nlh->nlmsg_type);break;}? ?return 0; }? ?static void netlink_kernel_rcv(struct sk_buff *skb) {int res; res = netlink_rcv_skb(skb, &netlink_kernel_rcv_msg);return; }// 模塊入口函數 static int __init nlkernel_init(void) {log("nlkernel init \r\n");// 注冊netlink協議 nlsock = netlink_kernel_create(&init_net, NETLINK_TEST_MODULE, 0, netlink_kernel_rcv, NULL, THIS_MODULE);if (!nlsock) {log("netlink module init fail \r\n");return -1;}return 0; }// 模塊退出函數 static void __exit nlkernel_exit(void) {// 注銷netlink協議 if(nlsock) {netlink_kernel_release(nlsock);nlsock = NULL; }log("nlkernel exit \r\n");return ; }module_init(nlkernel_init) module_exit(nlkernel_exit) MODULE_AUTHOR("mason"); MODULE_DESCRIPTION("netlink kernel test"); MODULE_LICENSE("GPL");nlkernel.h
#ifndef __NLKERNEL_H__ #define __NLKERNEL_H__ #define log(fmt, arg...) printk(KERN_INFO"[bfd] %s:%d "fmt, __FUNCTION__, __LINE__, ##arg)#ifndef NIPQUAD #define NIPQUAD(addr) \((unsigned char *)&addr)[0], \((unsigned char *)&addr)[1], \((unsigned char *)&addr)[2], \((unsigned char *)&addr)[3] #endif#define NETLINK_TEST_MODULE 17 /* 定義 netlink 協議, */typedef enum netlink_msg_type {???????????? /* 定義 netlink 消息類型 */NLKERNEL_GET = NLMSG_MIN_TYPE +1, /* value : 17 */NLKERNEL_SET, /* value : 18 */NLKERNEL_END, }NETLINK_MSG_TYPE;#endifMakefile
obj-m := nlkernel.oPWD := $(shell pwd) KERNEL_DIR := "/usr/src/linux-headers-"$(shell uname -r)/modules:@$(MAKE) -C $(KERNEL_DIR) M=$(PWD) modules clean:@rm -rf *.ko *.o *.mod.c *symvers *order *cmd代碼托管在github 上:
git@github.com:FuYuanDe/nlnetlink.git
編譯完成后加載模塊查看效果:
insmod nlkernel.ko
dmesg
總結
以上是生活随笔為你收集整理的linux netlink 编程示例(一)内核端的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 年利率5%怎么算利息
- 下一篇: linux netlink 编程示例(二