#include <linux/socket.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <net/sock.h>
#include <net/tcp_states.h>
/* Sollte in .../include/linux/netlink.h stehen */
#define NETLINK_TEST 25
#define MY_NL_COMMAND 0x11
#define MY_MESSAGE "Answer from Kernel"
static struct sock *nl_sk = NULL;
static DEFINE_MUTEX(nltest_mutex);
static void
nltest_netlink_server(struct sk_buff *skb)
{
struct nlmsghdr *nlh, *hdr;
u32 pid;
struct sk_buff *ret_skb;
char *data_ptr;
printk("nltest_netlink_server(%p)\n", skb);
BUG_ON(!skb);
nlh = nlmsg_hdr(skb);
pid = nlh->nlmsg_pid;
printk("pid: %d, seq: %d, data: \"%s\"\n",
pid, nlh->nlmsg_seq,
(char *)nlmsg_data(nlh));
/* Antwort verschicken */
ret_skb = nlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
if (ret_skb == NULL) {
printk("%s: no mem\n", __FUNCTION__);
return;
}
/* Header vorbereiten */
hdr = nlmsg_put(ret_skb,0,nlh->nlmsg_seq,
NLMSG_DONE, strlen(MY_MESSAGE),0);
if(IS_ERR(hdr)) {
printk("nlmsg_put failed\n");
nlmsg_free( ret_skb );
return;
}
data_ptr = nlmsg_data(hdr);
strcpy(data_ptr, MY_MESSAGE);
nlmsg_end( ret_skb, nlh );
netlink_unicast(nl_sk, ret_skb, pid, MSG_DONTWAIT);
}
static int
__init nltest_module_init(void)
{
printk("nltest_module_init\n");
nl_sk = netlink_kernel_create(&init_net, NETLINK_TEST,
0, nltest_netlink_server, &nltest_mutex, THIS_MODULE );
return 0;
}
static void
__exit nltest_module_exit(void)
{
printk("nltest_module_exit\n");
if( nl_sk )
sock_release(nl_sk->sk_socket);
}
module_init(nltest_module_init);
module_exit(nltest_module_exit);
MODULE_LICENSE("GPL");