我正在嘗試編寫一個使用netlink與用戶進(jìn)程通信的linux內(nèi)核模塊。我之所以使用netlink,是因?yàn)槲乙涣鞯挠脩舫绦蛑荒苁褂锰捉幼诌M(jìn)行通信,而不能更改它以添加ioctl()或進(jìn)行其他操作。問題是我不知道該怎么做。我已經(jīng)用谷歌搜索過,但是我發(fā)現(xiàn)的所有示例都是像這樣的舊示例,對于當(dāng)前的內(nèi)核版本不再有效。我也看過這個SO問題,但是這里的示例使用libnl進(jìn)行套接字操作,但是我想堅持使用標(biāo)準(zhǔn)的套接字函數(shù)(由定義sys/socket.h)。因此,有人可以指導(dǎo)我在這里找到一些教程或指南,或者可以幫助我理解netlink的界面和用法的東西。我將高度贊賞一個工作示例,沒有什么花哨的地方,只是一個非?;镜氖纠?,該示例說明了如何建立從用戶程序中的套接字到內(nèi)核中的套接字的連接,然后將數(shù)據(jù)從用戶進(jìn)程發(fā)送到內(nèi)核并從內(nèi)核接收回來。另外,請不要告訴我看內(nèi)核代碼。我已經(jīng)在做,但是要花很多時間,而且我還剩很多。更新: 經(jīng)過大量的試驗(yàn)和錯誤,我得到了以下代碼,該代碼將消息從用戶程序發(fā)送到內(nèi)核,但是消息從內(nèi)核發(fā)送到用戶程序,即使用netlink_unicast()不起作用。它不僅不起作用,而且調(diào)用使系統(tǒng)掛起,然后我必須重新啟動計算機(jī)??梢哉堃粋€人看看并告訴我我在做什么錯。netlink_unicast()在以下代碼中對該調(diào)用進(jìn)行了注釋。對于內(nèi)核到用戶程序的消息,應(yīng)該不加注釋。用戶程序#include <sys/socket.h> #include <linux/netlink.h> #define NETLINK_USER 31 #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); 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 */ /* interested in group 1<<0 */ bind(sock_fd, (struct sockaddr*)&src_addr, sizeof(src_addr)); memset(&dest_addr, 0, sizeof(dest_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)); memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD)); nlh->nlmsg_len = NLMSG_SPACE(MAX_PAYLOAD); nlh->nlmsg_pid = getpid(); nlh->nlmsg_flags = 0; strcpy(NLMSG_DATA(nlh), "Hello"); 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;
3 回答

慕碼人2483693
TA貢獻(xiàn)1860條經(jīng)驗(yàn) 獲得超9個贊
它適用于內(nèi)核3.2。對于3.6或更高版本的內(nèi)核,需要對netlink_kernel_create功能進(jìn)行一些更改。
struct netlink_kernel_cfg cfg = {
.groups = 1,
.input = hello_nl_recv_msg,
};
printk("Entering: %s\n", __FUNCTION__);
nl_sk = netlink_kernel_create(&init_net, NETLINK_USER, &cfg);
添加回答
舉報
0/150
提交
取消