Skip to content

Commit

Permalink
unix_diag: Dumping all sockets core
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
xemul authored and davem330 committed Dec 16, 2011
1 parent 22931d3 commit 45a96b9
Showing 1 changed file with 75 additions and 1 deletion.
76 changes: 75 additions & 1 deletion net/unix/diag.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,83 @@
#define UNIX_DIAG_PUT(skb, attrtype, attrlen) \
RTA_DATA(__RTA_PUT(skb, attrtype, attrlen))

static int sk_diag_fill(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
u32 pid, u32 seq, u32 flags, int sk_ino)
{
unsigned char *b = skb_tail_pointer(skb);
struct nlmsghdr *nlh;
struct unix_diag_msg *rep;

nlh = NLMSG_PUT(skb, pid, seq, SOCK_DIAG_BY_FAMILY, sizeof(*rep));
nlh->nlmsg_flags = flags;

rep = NLMSG_DATA(nlh);

rep->udiag_family = AF_UNIX;
rep->udiag_type = sk->sk_type;
rep->udiag_state = sk->sk_state;
rep->udiag_ino = sk_ino;
sock_diag_save_cookie(sk, rep->udiag_cookie);

nlh->nlmsg_len = skb_tail_pointer(skb) - b;
return skb->len;

nlmsg_failure:
nlmsg_trim(skb, b);
return -EMSGSIZE;
}

static int sk_diag_dump(struct sock *sk, struct sk_buff *skb, struct unix_diag_req *req,
u32 pid, u32 seq, u32 flags)
{
int sk_ino;

unix_state_lock(sk);
sk_ino = sock_i_ino(sk);
unix_state_unlock(sk);

if (!sk_ino)
return 0;

return sk_diag_fill(sk, skb, req, pid, seq, flags, sk_ino);
}

static int unix_diag_dump(struct sk_buff *skb, struct netlink_callback *cb)
{
return 0;
struct unix_diag_req *req;
int num, s_num, slot, s_slot;

req = NLMSG_DATA(cb->nlh);

s_slot = cb->args[0];
num = s_num = cb->args[1];

spin_lock(&unix_table_lock);
for (slot = s_slot; slot <= UNIX_HASH_SIZE; s_num = 0, slot++) {
struct sock *sk;
struct hlist_node *node;

num = 0;
sk_for_each(sk, node, &unix_socket_table[slot]) {
if (num < s_num)
goto next;
if (!(req->udiag_states & (1 << sk->sk_state)))
goto next;
if (sk_diag_dump(sk, skb, req,
NETLINK_CB(cb->skb).pid,
cb->nlh->nlmsg_seq,
NLM_F_MULTI) < 0)
goto done;
next:
num++;
}
}
done:
spin_unlock(&unix_table_lock);
cb->args[0] = slot;
cb->args[1] = num;

return skb->len;
}

static int unix_diag_get_exact(struct sk_buff *in_skb,
Expand Down

0 comments on commit 45a96b9

Please sign in to comment.