Python 4 以上内核中的 Netlink 多播通信
Python Netlink Multicast Communication in Kernels above 4
我试图在 4 (4.1) 以上的内核上重现之前 SO post 中的示例:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netlink.h>
#include <net/netlink.h>
#include <net/net_namespace.h>
/* Protocol family, consistent in both kernel prog and user prog. */
#define MYPROTO NETLINK_USERSOCK
/* Multicast group, consistent in both kernel prog and user prog. */
#define MYGRP 31
static struct sock *nl_sk = NULL;
static void send_to_user(void)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
char *msg = "Hello from kernel";
int msg_size = strlen(msg) + 1;
int res;
pr_info("Creating skb.\n");
skb = nlmsg_new(NLMSG_ALIGN(msg_size + 1), GFP_KERNEL);
if (!skb) {
pr_err("Allocation failure.\n");
return;
}
nlh = nlmsg_put(skb, 0, 1, NLMSG_DONE, msg_size + 1, 0);
strcpy(nlmsg_data(nlh), msg);
pr_info("Sending skb.\n");
res = nlmsg_multicast(nl_sk, skb, 0, MYGRP, GFP_KERNEL);
if (res < 0)
pr_info("nlmsg_multicast() error: %d\n", res);
else
pr_info("Success.\n");
}
static int __init hello_init(void)
{
pr_info("Inserting hello module.\n");
nl_sk = netlink_kernel_create(&init_net, MYPROTO, NULL);
if (!nl_sk) {
pr_err("Error creating socket.\n");
return -10;
}
send_to_user();
netlink_kernel_release(nl_sk);
return 0;
}
static void __exit hello_exit(void)
{
pr_info("Exiting hello module.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
然而,编译工作正常,但是当我插入模块时,它 returns:
nlmsg_multicast() error: -3
我什至不知道在哪里可以查找错误代码以了解 -3 在这种情况下的含义(我搜索了 here,但找不到任何关于错误代码的有用信息)。
只是为了确定,我 post 用户空间代码 (Python) 也:
由于评论已编辑:(但仍然无法正常工作)
#!/usr/bin/env python
import socket
import os
import time
sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, socket.NETLINK_USERSOCK)
# 270 is SOL_NETLINK and 1 is NETLINK_ADD_MEMBERSHIP
sock.setsockopt(270, 1, 31)
while 1:
try:
print sock.recvfrom(1024)
except socket.error, e:
print 'Exception'
您忘记绑定套接字。 :-)
我对 Python 不是很流利,所以仅将其用作起点(在 socket
和 setsockopt
之间):
sock.bind((0, 0))
那给我打印了一堆垃圾,其中我能看到
Hello from kernel
顺便说一句:当 nlmsg_multicast()
抛出 ESRCH
时,通常(或者可能总是)因为没有客户端在监听。
先打开客户端,然后尝试从内核发送消息
否则,您始终可以忽略对您的用例有意义的错误代码。
我试图在 4 (4.1) 以上的内核上重现之前 SO post 中的示例:
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/netlink.h>
#include <net/netlink.h>
#include <net/net_namespace.h>
/* Protocol family, consistent in both kernel prog and user prog. */
#define MYPROTO NETLINK_USERSOCK
/* Multicast group, consistent in both kernel prog and user prog. */
#define MYGRP 31
static struct sock *nl_sk = NULL;
static void send_to_user(void)
{
struct sk_buff *skb;
struct nlmsghdr *nlh;
char *msg = "Hello from kernel";
int msg_size = strlen(msg) + 1;
int res;
pr_info("Creating skb.\n");
skb = nlmsg_new(NLMSG_ALIGN(msg_size + 1), GFP_KERNEL);
if (!skb) {
pr_err("Allocation failure.\n");
return;
}
nlh = nlmsg_put(skb, 0, 1, NLMSG_DONE, msg_size + 1, 0);
strcpy(nlmsg_data(nlh), msg);
pr_info("Sending skb.\n");
res = nlmsg_multicast(nl_sk, skb, 0, MYGRP, GFP_KERNEL);
if (res < 0)
pr_info("nlmsg_multicast() error: %d\n", res);
else
pr_info("Success.\n");
}
static int __init hello_init(void)
{
pr_info("Inserting hello module.\n");
nl_sk = netlink_kernel_create(&init_net, MYPROTO, NULL);
if (!nl_sk) {
pr_err("Error creating socket.\n");
return -10;
}
send_to_user();
netlink_kernel_release(nl_sk);
return 0;
}
static void __exit hello_exit(void)
{
pr_info("Exiting hello module.\n");
}
module_init(hello_init);
module_exit(hello_exit);
MODULE_LICENSE("GPL");
然而,编译工作正常,但是当我插入模块时,它 returns:
nlmsg_multicast() error: -3
我什至不知道在哪里可以查找错误代码以了解 -3 在这种情况下的含义(我搜索了 here,但找不到任何关于错误代码的有用信息)。
只是为了确定,我 post 用户空间代码 (Python) 也:
由于评论已编辑:(但仍然无法正常工作)
#!/usr/bin/env python
import socket
import os
import time
sock = socket.socket(socket.AF_NETLINK, socket.SOCK_DGRAM, socket.NETLINK_USERSOCK)
# 270 is SOL_NETLINK and 1 is NETLINK_ADD_MEMBERSHIP
sock.setsockopt(270, 1, 31)
while 1:
try:
print sock.recvfrom(1024)
except socket.error, e:
print 'Exception'
您忘记绑定套接字。 :-)
我对 Python 不是很流利,所以仅将其用作起点(在 socket
和 setsockopt
之间):
sock.bind((0, 0))
那给我打印了一堆垃圾,其中我能看到
Hello from kernel
顺便说一句:当 nlmsg_multicast()
抛出 ESRCH
时,通常(或者可能总是)因为没有客户端在监听。
先打开客户端,然后尝试从内核发送消息
否则,您始终可以忽略对您的用例有意义的错误代码。