xref: /linux/net/tipc/diag.c (revision 9a07efa9aea2f4a59f35da0785a4e6a6b5a96192)
1c30b70deSGhantaKrishnamurthy MohanKrishna /*
2c30b70deSGhantaKrishnamurthy MohanKrishna  * net/tipc/diag.c: TIPC socket diag
3c30b70deSGhantaKrishnamurthy MohanKrishna  *
4c30b70deSGhantaKrishnamurthy MohanKrishna  * Copyright (c) 2018, Ericsson AB
5c30b70deSGhantaKrishnamurthy MohanKrishna  * All rights reserved.
6c30b70deSGhantaKrishnamurthy MohanKrishna  *
7c30b70deSGhantaKrishnamurthy MohanKrishna  * Redistribution and use in source and binary forms, with or without
8c30b70deSGhantaKrishnamurthy MohanKrishna  * modification, are permitted provided that the following conditions are met:
9c30b70deSGhantaKrishnamurthy MohanKrishna  *
10c30b70deSGhantaKrishnamurthy MohanKrishna  * 1. Redistributions of source code must retain the above copyright
11c30b70deSGhantaKrishnamurthy MohanKrishna  *    notice, this list of conditions and the following disclaimer.
12c30b70deSGhantaKrishnamurthy MohanKrishna  * 2. Redistributions in binary form must reproduce the above copyright
13c30b70deSGhantaKrishnamurthy MohanKrishna  *    notice, this list of conditions and the following disclaimer in the
14c30b70deSGhantaKrishnamurthy MohanKrishna  *    documentation and/or other materials provided with the distribution.
15c30b70deSGhantaKrishnamurthy MohanKrishna  * 3. Neither the names of the copyright holders nor the names of its
16c30b70deSGhantaKrishnamurthy MohanKrishna  *    contributors may be used to endorse or promote products derived from
17c30b70deSGhantaKrishnamurthy MohanKrishna  *    this software without specific prior written permission.
18c30b70deSGhantaKrishnamurthy MohanKrishna  *
19c30b70deSGhantaKrishnamurthy MohanKrishna  * Alternatively, this software may be distributed under the terms of the
20c30b70deSGhantaKrishnamurthy MohanKrishna  * GNU General Public License ("GPL") version 2 as published by the Free
21c30b70deSGhantaKrishnamurthy MohanKrishna  * Software Foundation.
22c30b70deSGhantaKrishnamurthy MohanKrishna  *
23c30b70deSGhantaKrishnamurthy MohanKrishna  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "ASIS"
24c30b70deSGhantaKrishnamurthy MohanKrishna  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,THE
25c30b70deSGhantaKrishnamurthy MohanKrishna  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
26c30b70deSGhantaKrishnamurthy MohanKrishna  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
27c30b70deSGhantaKrishnamurthy MohanKrishna  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
28c30b70deSGhantaKrishnamurthy MohanKrishna  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
29c30b70deSGhantaKrishnamurthy MohanKrishna  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
30c30b70deSGhantaKrishnamurthy MohanKrishna  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
31c30b70deSGhantaKrishnamurthy MohanKrishna  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
32c30b70deSGhantaKrishnamurthy MohanKrishna  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
33c30b70deSGhantaKrishnamurthy MohanKrishna  * POSSIBILITY OF SUCH DAMAGE.
34c30b70deSGhantaKrishnamurthy MohanKrishna  */
35c30b70deSGhantaKrishnamurthy MohanKrishna 
36c30b70deSGhantaKrishnamurthy MohanKrishna #include "core.h"
37c30b70deSGhantaKrishnamurthy MohanKrishna #include "socket.h"
38c30b70deSGhantaKrishnamurthy MohanKrishna #include <linux/sock_diag.h>
39c30b70deSGhantaKrishnamurthy MohanKrishna #include <linux/tipc_sockets_diag.h>
40c30b70deSGhantaKrishnamurthy MohanKrishna 
41c30b70deSGhantaKrishnamurthy MohanKrishna static u64 __tipc_diag_gen_cookie(struct sock *sk)
42c30b70deSGhantaKrishnamurthy MohanKrishna {
43c30b70deSGhantaKrishnamurthy MohanKrishna 	u32 res[2];
44c30b70deSGhantaKrishnamurthy MohanKrishna 
45c30b70deSGhantaKrishnamurthy MohanKrishna 	sock_diag_save_cookie(sk, res);
46c30b70deSGhantaKrishnamurthy MohanKrishna 	return *((u64 *)res);
47c30b70deSGhantaKrishnamurthy MohanKrishna }
48c30b70deSGhantaKrishnamurthy MohanKrishna 
49c30b70deSGhantaKrishnamurthy MohanKrishna static int __tipc_add_sock_diag(struct sk_buff *skb,
50c30b70deSGhantaKrishnamurthy MohanKrishna 				struct netlink_callback *cb,
51c30b70deSGhantaKrishnamurthy MohanKrishna 				struct tipc_sock *tsk)
52c30b70deSGhantaKrishnamurthy MohanKrishna {
53c30b70deSGhantaKrishnamurthy MohanKrishna 	struct tipc_sock_diag_req *req = nlmsg_data(cb->nlh);
54c30b70deSGhantaKrishnamurthy MohanKrishna 	struct nlmsghdr *nlh;
55c30b70deSGhantaKrishnamurthy MohanKrishna 	int err;
56c30b70deSGhantaKrishnamurthy MohanKrishna 
57c30b70deSGhantaKrishnamurthy MohanKrishna 	nlh = nlmsg_put_answer(skb, cb, SOCK_DIAG_BY_FAMILY, 0,
58c30b70deSGhantaKrishnamurthy MohanKrishna 			       NLM_F_MULTI);
59c30b70deSGhantaKrishnamurthy MohanKrishna 	if (!nlh)
60c30b70deSGhantaKrishnamurthy MohanKrishna 		return -EMSGSIZE;
61c30b70deSGhantaKrishnamurthy MohanKrishna 
62e41f0548SCong Wang 	err = tipc_sk_fill_sock_diag(skb, cb, tsk, req->tidiag_states,
63c30b70deSGhantaKrishnamurthy MohanKrishna 				     __tipc_diag_gen_cookie);
64c30b70deSGhantaKrishnamurthy MohanKrishna 	if (err)
65c30b70deSGhantaKrishnamurthy MohanKrishna 		return err;
66c30b70deSGhantaKrishnamurthy MohanKrishna 
67c30b70deSGhantaKrishnamurthy MohanKrishna 	nlmsg_end(skb, nlh);
68c30b70deSGhantaKrishnamurthy MohanKrishna 	return 0;
69c30b70deSGhantaKrishnamurthy MohanKrishna }
70c30b70deSGhantaKrishnamurthy MohanKrishna 
71c30b70deSGhantaKrishnamurthy MohanKrishna static int tipc_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
72c30b70deSGhantaKrishnamurthy MohanKrishna {
73c30b70deSGhantaKrishnamurthy MohanKrishna 	return tipc_nl_sk_walk(skb, cb, __tipc_add_sock_diag);
74c30b70deSGhantaKrishnamurthy MohanKrishna }
75c30b70deSGhantaKrishnamurthy MohanKrishna 
76c30b70deSGhantaKrishnamurthy MohanKrishna static int tipc_sock_diag_handler_dump(struct sk_buff *skb,
77c30b70deSGhantaKrishnamurthy MohanKrishna 				       struct nlmsghdr *h)
78c30b70deSGhantaKrishnamurthy MohanKrishna {
79c30b70deSGhantaKrishnamurthy MohanKrishna 	int hdrlen = sizeof(struct tipc_sock_diag_req);
80c30b70deSGhantaKrishnamurthy MohanKrishna 	struct net *net = sock_net(skb->sk);
81c30b70deSGhantaKrishnamurthy MohanKrishna 
82c30b70deSGhantaKrishnamurthy MohanKrishna 	if (nlmsg_len(h) < hdrlen)
83c30b70deSGhantaKrishnamurthy MohanKrishna 		return -EINVAL;
84c30b70deSGhantaKrishnamurthy MohanKrishna 
85c30b70deSGhantaKrishnamurthy MohanKrishna 	if (h->nlmsg_flags & NLM_F_DUMP) {
86c30b70deSGhantaKrishnamurthy MohanKrishna 		struct netlink_dump_control c = {
87*9a07efa9SCong Wang 			.start = tipc_dump_start,
88c30b70deSGhantaKrishnamurthy MohanKrishna 			.dump = tipc_diag_dump,
89*9a07efa9SCong Wang 			.done = tipc_dump_done,
90c30b70deSGhantaKrishnamurthy MohanKrishna 		};
91c30b70deSGhantaKrishnamurthy MohanKrishna 		netlink_dump_start(net->diag_nlsk, skb, h, &c);
92c30b70deSGhantaKrishnamurthy MohanKrishna 		return 0;
93c30b70deSGhantaKrishnamurthy MohanKrishna 	}
94c30b70deSGhantaKrishnamurthy MohanKrishna 	return -EOPNOTSUPP;
95c30b70deSGhantaKrishnamurthy MohanKrishna }
96c30b70deSGhantaKrishnamurthy MohanKrishna 
97c30b70deSGhantaKrishnamurthy MohanKrishna static const struct sock_diag_handler tipc_sock_diag_handler = {
98c30b70deSGhantaKrishnamurthy MohanKrishna 	.family = AF_TIPC,
99c30b70deSGhantaKrishnamurthy MohanKrishna 	.dump = tipc_sock_diag_handler_dump,
100c30b70deSGhantaKrishnamurthy MohanKrishna };
101c30b70deSGhantaKrishnamurthy MohanKrishna 
102c30b70deSGhantaKrishnamurthy MohanKrishna static int __init tipc_diag_init(void)
103c30b70deSGhantaKrishnamurthy MohanKrishna {
104c30b70deSGhantaKrishnamurthy MohanKrishna 	return sock_diag_register(&tipc_sock_diag_handler);
105c30b70deSGhantaKrishnamurthy MohanKrishna }
106c30b70deSGhantaKrishnamurthy MohanKrishna 
107c30b70deSGhantaKrishnamurthy MohanKrishna static void __exit tipc_diag_exit(void)
108c30b70deSGhantaKrishnamurthy MohanKrishna {
109c30b70deSGhantaKrishnamurthy MohanKrishna 	sock_diag_unregister(&tipc_sock_diag_handler);
110c30b70deSGhantaKrishnamurthy MohanKrishna }
111c30b70deSGhantaKrishnamurthy MohanKrishna 
112c30b70deSGhantaKrishnamurthy MohanKrishna module_init(tipc_diag_init);
113c30b70deSGhantaKrishnamurthy MohanKrishna module_exit(tipc_diag_exit);
114c30b70deSGhantaKrishnamurthy MohanKrishna 
115c30b70deSGhantaKrishnamurthy MohanKrishna MODULE_LICENSE("Dual BSD/GPL");
116c30b70deSGhantaKrishnamurthy MohanKrishna MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, AF_TIPC);
117