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 不是很流利,所以仅将其用作起点(在 socketsetsockopt 之间):

sock.bind((0, 0))

那给我打印了一堆垃圾,其中我能看到

Hello from kernel

顺便说一句:当 nlmsg_multicast() 抛出 ESRCH 时,通常(或者可能总是)因为没有客户端在监听。

先打开客户端,然后尝试从内核发送消息

否则,您始终可以忽略对您的用例有意义的错误代码。