84425e52 |
1 | /* ltt-control.c |
2 | * |
3 | * LTT control module over a netlink socket. |
4 | * |
5 | * Inspired from Relay Apps, by Tom Zanussi and iptables |
6 | * |
7 | * Copyright 2005 - |
8 | * Mathieu Desnoyers <mathieu.desnoyers@polymtl.ca> |
9 | */ |
10 | |
11 | #include <linux/init.h> |
12 | #include <linux/module.h> |
13 | #include <linux/ltt-core.h> |
14 | #include <linux/netlink.h> |
15 | #include <linux/inet.h> |
16 | #include <linux/ip.h> |
17 | #include <linux/security.h> |
18 | #include <linux/skbuff.h> |
19 | #include <linux/types.h> |
20 | #include <net/sock.h> |
21 | #include "ltt-control.h" |
22 | |
23 | |
24 | #define LTTCTLM_BASE 0x10 |
25 | #define LTTCTLM_CONTROL (LTTCTLM_BASE + 1) /* LTT control message */ |
26 | |
27 | static struct sock *socket; |
28 | |
29 | void ltt_control_input(struct sock *sk, int len) |
30 | { |
31 | struct sk_buff *skb; |
32 | struct nlmsghdr *nlh = NULL; |
33 | u8 *payload = NULL; |
34 | lttctl_peer_msg_t *msg; |
35 | int err; |
36 | |
37 | printk(KERN_ALERT "ltt-control ltt_control_input\n"); |
38 | |
39 | while ((skb = skb_dequeue(&sk->sk_receive_queue)) |
40 | != NULL) { |
41 | |
42 | nlh = (struct nlmsghdr *)skb->data; |
43 | |
44 | if(security_netlink_recv(skb)) { |
45 | netlink_ack(skb, nlh, EPERM); |
46 | kfree_skb(skb); |
47 | continue; |
48 | } |
49 | |
50 | /* process netlink message pointed by skb->data */ |
51 | err = EINVAL; |
52 | payload = NLMSG_DATA(nlh); |
53 | /* process netlink message with header pointed by |
54 | * nlh and payload pointed by payload |
55 | */ |
56 | if(nlh->nlmsg_len != sizeof(lttctl_peer_msg_t) + sizeof(struct nlmsghdr)) { |
57 | printk(KERN_ALERT "ltt-control bad message length\n"); |
58 | netlink_ack(skb, nlh, EINVAL); |
59 | kfree_skb(skb); |
60 | continue; |
61 | } |
62 | msg = (lttctl_peer_msg_t*)payload; |
63 | |
64 | switch(msg->op) { |
65 | case OP_CREATE: |
66 | err = ltt_control(LTT_CONTROL_CREATE_TRACE, msg->trace_name, |
67 | msg->args); |
68 | break; |
69 | case OP_DESTROY: |
70 | err = ltt_control(LTT_CONTROL_DESTROY_TRACE, msg->trace_name, |
71 | msg->args); |
72 | break; |
73 | case OP_START: |
74 | err = ltt_control(LTT_CONTROL_START, msg->trace_name, |
75 | msg->args); |
76 | break; |
77 | case OP_STOP: |
78 | err = ltt_control(LTT_CONTROL_STOP, msg->trace_name, |
79 | msg->args); |
80 | break; |
81 | default: |
82 | err = EBADRQC; |
83 | printk(KERN_INFO "ltt-control invalid operation\n"); |
84 | } |
85 | netlink_ack(skb, nlh, err); |
86 | kfree_skb(skb); |
87 | } |
88 | } |
89 | |
90 | |
91 | static int ltt_control_init(void) |
92 | { |
93 | printk(KERN_ALERT "ltt-control init\n"); |
94 | |
95 | socket = netlink_kernel_create(NETLINK_LTT, 1, |
96 | ltt_control_input, THIS_MODULE); |
97 | if(socket == NULL) return -EPERM; |
98 | else return 0; |
99 | } |
100 | |
101 | static void ltt_control_exit(void) |
102 | { |
103 | printk(KERN_ALERT "ltt-control exit\n"); |
104 | |
105 | sock_release(socket->sk_socket); |
106 | } |
107 | |
108 | |
109 | module_init(ltt_control_init) |
110 | module_exit(ltt_control_exit) |
111 | |
112 | MODULE_LICENSE("GPL"); |
113 | MODULE_AUTHOR("Mathieu Desnoyers"); |
114 | MODULE_DESCRIPTION("Linux Trace Toolkit Controller"); |
115 | |