aboutsummaryrefslogtreecommitdiffstats
path: root/net/unix/diag.c
diff options
context:
space:
mode:
authorPavel Emelyanov <xemul@parallels.com>2011-12-14 21:44:52 -0500
committerDavid S. Miller <davem@davemloft.net>2011-12-16 13:48:28 -0500
commit45a96b9be6ec1b7d248642d17ceee59ff5f64451 (patch)
tree9623dc58bd01b23a70b3ef261e69b533b717ec46 /net/unix/diag.c
parent22931d3b906cd0a1726a49a09713f9220a5fab8a (diff)
unix_diag: Dumping all sockets core
Walk the unix sockets table and fill the core response structure, which includes type, state and inode. Signed-off-by: Pavel Emelyanov <xemul@parallels.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'net/unix/diag.c')
-rw-r--r--net/unix/diag.c76
1 files changed, 75 insertions, 1 deletions
diff --git a/net/unix/diag.c b/net/unix/diag.c
index 6be16c0ad38f..86d85abf90c6 100644
--- a/net/unix/diag.c
+++ b/net/unix/diag.c
@@ -10,9 +10,83 @@
10#define UNIX_DIAG_PUT(skb, attrtype, attrlen) \ 10#define UNIX_DIAG_PUT(skb, attrtype, attrlen) \
11 RTA_DATA(__RTA_PUT(skb, attrtype, attrlen)) 11 RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))
12 12
13static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
14 u32 pid, u32 seq, u32 flags, int sk_ino)
15{
16 unsigned char *b = skb_tail_pointer(skb);
17 struct nlmsghdr *nlh;
18 struct unix_diag_msg *rep;
19
20 nlh = NLMSG_PUT(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep));
21 nlh->nlmsg_flags = flags;
22
23 rep = NLMSG_DATA(nlh);
24
25 rep->udiag_family = AF_UNIX;
26 rep->udiag_type = sk->sk_type;
27 rep->udiag_state = sk->sk_state;
28 rep->udiag_ino = sk_ino;
29 sock_diag_save_cookie(sk, rep->udiag_cookie);
30
31 nlh->nlmsg_len = skb_tail_pointer(skb) - b;
32 return skb->len;
33
34nlmsg_failure:
35 nlmsg_trim(skb, b);
36 return -EMSGSIZE;
37}
38
39static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
40 u32 pid, u32 seq, u32 flags)
41{
42 int sk_ino;
43
44 unix_state_lock(sk);
45 sk_ino = sock_i_ino(sk);
46 unix_state_unlock(sk);
47
48 if (!sk_ino)
49 return 0;
50
51 return sk_diag_fill(sk, skb, req, pid, seq, flags, sk_ino);
52}
53
13static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb) 54static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
14{ 55{
15 return 0; 56 struct unix_diag_req *req;
57 int num, s_num, slot, s_slot;
58
59 req = NLMSG_DATA(cb->nlh);
60
61 s_slot = cb->args[0];
62 num = s_num = cb->args[1];
63
64 spin_lock(&unix_table_lock);
65 for (slot = s_slot; slot <= UNIX_HASH_SIZE; s_num = 0, slot++) {
66 struct sock *sk;
67 struct hlist_node *node;
68
69 num = 0;
70 sk_for_each(sk, node, &unix_socket_table[slot]) {
71 if (num < s_num)
72 goto next;
73 if (!(req->udiag_states & (1 << sk->sk_state)))
74 goto next;
75 if (sk_diag_dump(sk, skb, req,
76 NETLINK_CB(cb->skb).pid,
77 cb->nlh->nlmsg_seq,
78 NLM_F_MULTI) < 0)
79 goto done;
80next:
81 num++;
82 }
83 }
84done:
85 spin_unlock(&unix_table_lock);
86 cb->args[0] = slot;
87 cb->args[1] = num;
88
89 return skb->len;
16} 90}
17 91
18static int unix_diag_get_exact(struct sk_buff *in_skb, 92static int unix_diag_get_exact(struct sk_buff *in_skb,