-
Notifications
You must be signed in to change notification settings - Fork 25
/
netlink_test.c
73 lines (55 loc) · 1.68 KB
/
netlink_test.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#include <net/sock.h>
#include <linux/module.h>
#include <linux/netlink.h>
#include <linux/skbuff.h>
#define NETLINK_TEST 17
struct sock *nl_sock = NULL;
static void netlink_test_recv_msg(struct sk_buff *skb)
{
struct sk_buff *skb_out;
struct nlmsghdr *nlh;
int msg_size;
char *msg;
int pid;
int res;
nlh = (struct nlmsghdr *)skb->data;
pid = nlh->nlmsg_pid; /* pid of sending process */
msg = (char *)nlmsg_data(nlh);
msg_size = strlen(msg);
printk(KERN_INFO "netlink_test: Received from pid %d: %s\n", pid, msg);
// create reply
skb_out = nlmsg_new(msg_size, 0);
if (!skb_out) {
printk(KERN_ERR "netlink_test: Failed to allocate new skb\n");
return;
}
// put received message into reply
nlh = nlmsg_put(skb_out, 0, 0, NLMSG_DONE, msg_size, 0);
NETLINK_CB(skb_out).dst_group = 0; /* not in mcast group */
strncpy(nlmsg_data(nlh), msg, msg_size);
printk(KERN_INFO "netlink_test: Send %s\n", msg);
res = nlmsg_unicast(nl_sock, skb_out, pid);
if (res < 0)
printk(KERN_INFO "netlink_test: Error while sending skb to user\n");
}
static int __init netlink_test_init(void)
{
printk(KERN_INFO "netlink_test: Init module\n");
struct netlink_kernel_cfg cfg = {
.input = netlink_test_recv_msg,
};
nl_sock = netlink_kernel_create(&init_net, NETLINK_TEST, &cfg);
if (!nl_sock) {
printk(KERN_ALERT "netlink_test: Error creating socket.\n");
return -10;
}
return 0;
}
static void __exit netlink_test_exit(void)
{
printk(KERN_INFO "netlink_test: Exit module\n");
netlink_kernel_release(nl_sock);
}
module_init(netlink_test_init);
module_exit(netlink_test_exit);
MODULE_LICENSE("GPL");