0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 #include "core.h"
0037 #include "socket.h"
0038 #include <linux/sock_diag.h>
0039 #include <linux/tipc_sockets_diag.h>
0040
0041 static u64 __tipc_diag_gen_cookie(struct sock *sk)
0042 {
0043 u32 res[2];
0044
0045 sock_diag_save_cookie(sk, res);
0046 return *((u64 *)res);
0047 }
0048
0049 static int __tipc_add_sock_diag(struct sk_buff *skb,
0050 struct netlink_callback *cb,
0051 struct tipc_sock *tsk)
0052 {
0053 struct tipc_sock_diag_req *req = nlmsg_data(cb->nlh);
0054 struct nlmsghdr *nlh;
0055 int err;
0056
0057 nlh = nlmsg_put_answer(skb, cb, SOCK_DIAG_BY_FAMILY, 0,
0058 NLM_F_MULTI);
0059 if (!nlh)
0060 return -EMSGSIZE;
0061
0062 err = tipc_sk_fill_sock_diag(skb, cb, tsk, req->tidiag_states,
0063 __tipc_diag_gen_cookie);
0064 if (err)
0065 return err;
0066
0067 nlmsg_end(skb, nlh);
0068 return 0;
0069 }
0070
0071 static int tipc_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
0072 {
0073 return tipc_nl_sk_walk(skb, cb, __tipc_add_sock_diag);
0074 }
0075
0076 static int tipc_sock_diag_handler_dump(struct sk_buff *skb,
0077 struct nlmsghdr *h)
0078 {
0079 int hdrlen = sizeof(struct tipc_sock_diag_req);
0080 struct net *net = sock_net(skb->sk);
0081
0082 if (nlmsg_len(h) < hdrlen)
0083 return -EINVAL;
0084
0085 if (h->nlmsg_flags & NLM_F_DUMP) {
0086 struct netlink_dump_control c = {
0087 .start = tipc_dump_start,
0088 .dump = tipc_diag_dump,
0089 .done = tipc_dump_done,
0090 };
0091 netlink_dump_start(net->diag_nlsk, skb, h, &c);
0092 return 0;
0093 }
0094 return -EOPNOTSUPP;
0095 }
0096
0097 static const struct sock_diag_handler tipc_sock_diag_handler = {
0098 .family = AF_TIPC,
0099 .dump = tipc_sock_diag_handler_dump,
0100 };
0101
0102 static int __init tipc_diag_init(void)
0103 {
0104 return sock_diag_register(&tipc_sock_diag_handler);
0105 }
0106
0107 static void __exit tipc_diag_exit(void)
0108 {
0109 sock_diag_unregister(&tipc_sock_diag_handler);
0110 }
0111
0112 module_init(tipc_diag_init);
0113 module_exit(tipc_diag_exit);
0114
0115 MODULE_LICENSE("Dual BSD/GPL");
0116 MODULE_ALIAS_NET_PF_PROTO_TYPE(PF_NETLINK, NETLINK_SOCK_DIAG, AF_TIPC);