Issue
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.\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");
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'
Solution
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.
Answered By - Yd Ahhrk