Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
650 views
in Technique[技术] by (71.8m points)

c - Python Netlink Multicast Communication in Kernels above 4

I was trying to reproduce the example from a previous SO post on a kernel above 4 (4.1):

#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.
");
    skb = nlmsg_new(NLMSG_ALIGN(msg_size + 1), GFP_KERNEL);
    if (!skb) {
        pr_err("Allocation failure.
");
        return;
    }

    nlh = nlmsg_put(skb, 0, 1, NLMSG_DONE, msg_size + 1, 0);
    strcpy(nlmsg_data(nlh), msg);

    pr_info("Sending skb.
");
    res = nlmsg_multicast(nl_sk, skb, 0, MYGRP, GFP_KERNEL);
    if (res < 0)
        pr_info("nlmsg_multicast() error: %d
", res);
    else
        pr_info("Success.
");
}

static int __init hello_init(void)
{
    pr_info("Inserting hello module.
");

    nl_sk = netlink_kernel_create(&init_net, MYPROTO, NULL);
    if (!nl_sk) {
        pr_err("Error creating socket.
");
        return -10;
    }

    send_to_user();

    netlink_kernel_release(nl_sk);
    return 0;
}

static void __exit hello_exit(void)
{
    pr_info("Exiting hello module.
");
}

module_init(hello_init);
module_exit(hello_exit);

MODULE_LICENSE("GPL");

However, compilation works fine, but when I insert the module, it returns:

nlmsg_multicast() error: -3

I dont even know, where I can lookup the error codes to learn, what -3 means in this context (I searched here, but was unable to find anything useful, regarding the error code).

Just to be sure, I post the userland code (Python) also:

EDITED due to a comment: (but still not working)

#!/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'
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You forgot to bind the socket. :-)

I'm not very fluent with Python, so use this only as a starting point (between the socket and the setsockopt):

sock.bind((0, 0))

That prints me a bunch of garbage, among which I can see

Hello from kernel

By the way: When nlmsg_multicast() throws ESRCH, it's usually (or maybe always) because there were no clients listening.

First open the client, then try to send the message from the kernel.

Otherwise you can always ignore that error code it that makes sense for your use case.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...