linux-man.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
From: "Dmitry V. Levin" <ldv-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
To: mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org
Cc: Pavel Emelyanov <xemul-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org>,
	linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
Subject: [PATCH 2/4] sock_diag.7: Add EXAMPLE program
Date: Tue, 15 Mar 2016 20:26:05 +0300	[thread overview]
Message-ID: <20160315172605.GC2903@altlinux.org> (raw)
In-Reply-To: <cover.1458040999.git.ldv-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>

Signed-off-by: Dmitry V. Levin <ldv-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
Acked-by: Pavel Emelyanov <xemul-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org>
---
 man7/sock_diag.7 | 188 +++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 188 insertions(+)

diff --git a/man7/sock_diag.7 b/man7/sock_diag.7
index d1be9cf..776e2c9 100644
--- a/man7/sock_diag.7
+++ b/man7/sock_diag.7
@@ -626,6 +626,194 @@ was introduced in Linux 3.3.
 and
 .BR INET_DIAG_SKMEMINFO
 were introduced in Linux 3.6.
+.SH EXAMPLE
+The following example program prints inode number, peer's inode number,
+and name of all UNIX domain sockets in the current namespace.
+
+.nf
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+#include <linux/netlink.h>
+#include <linux/rtnetlink.h>
+#include <linux/sock_diag.h>
+#include <linux/unix_diag.h>
+
+static int
+send_query(int fd)
+{
+    struct sockaddr_nl nladdr = {
+        .nl_family = AF_NETLINK
+    };
+    struct
+    {
+        struct nlmsghdr nlh;
+        struct unix_diag_req udr;
+    } req = {
+        .nlh = {
+            .nlmsg_len = sizeof(req),
+            .nlmsg_type = SOCK_DIAG_BY_FAMILY,
+            .nlmsg_flags = NLM_F_REQUEST | NLM_F_DUMP
+        },
+        .udr = {
+            .sdiag_family = PF_UNIX,
+            .udiag_states = \-1,
+            .udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER
+        }
+    };
+    struct iovec iov = {
+        .iov_base = &req,
+        .iov_len = sizeof(req)
+    };
+    struct msghdr msg = {
+        .msg_name = (void *) &nladdr,
+        .msg_namelen = sizeof(nladdr),
+        .msg_iov = &iov,
+        .msg_iovlen = 1
+    };
+
+    for (;;) {
+        if (sendmsg(fd, &msg, 0) < 0) {
+            if (errno == EINTR)
+                continue;
+            perror("sendmsg");
+            return \-1;
+        }
+        return 0;
+    }
+}
+
+static int
+print_diag(const struct unix_diag_msg *diag, unsigned int len)
+{
+    if (len < NLMSG_LENGTH(sizeof(*diag))) {
+        fputs("short response\\n", stderr);
+        return \-1;
+    }
+    if (diag\->udiag_family != PF_UNIX) {
+        fprintf(stderr, "unexpected family %u\\n", diag\->udiag_family);
+        return \-1;
+    }
+
+    struct rtattr *attr;
+    unsigned int rta_len = len \- NLMSG_LENGTH(sizeof(*diag));
+    unsigned int peer = 0;
+    size_t path_len = 0;
+    char path[sizeof(((struct sockaddr_un *) 0)\->sun_path) + 1];
+
+    for (attr = (struct rtattr *) (diag + 1);
+             RTA_OK(attr, rta_len); attr = RTA_NEXT(attr, rta_len)) {
+        switch (attr\->rta_type) {
+            case UNIX_DIAG_NAME:
+                if (!path_len) {
+                    path_len = RTA_PAYLOAD(attr);
+                    if (path_len > sizeof(path) \- 1)
+                        path_len = sizeof(path) \- 1;
+                    memcpy(path, RTA_DATA(attr), path_len);
+                    path[path_len] = '\\0';
+                }
+                break;
+            case UNIX_DIAG_PEER:
+                if (RTA_PAYLOAD(attr) >= sizeof(peer))
+                    peer = *(unsigned int *) RTA_DATA(attr);
+                break;
+        }
+    }
+
+    printf("inode=%u", diag->udiag_ino);
+
+    if (peer)
+        printf(", peer=%u", peer);
+
+    if (path_len)
+        printf(", name=%s%s", *path ? "" : "@", *path ? path : path + 1);
+
+    putchar('\\n');
+    return 0;
+}
+
+static int
+receive_responses(int fd)
+{
+    long buf[8192 / sizeof(long)];
+    struct sockaddr_nl nladdr = {
+        .nl_family = AF_NETLINK
+    };
+    struct iovec iov = {
+        .iov_base = buf,
+        .iov_len = sizeof(buf)
+    };
+    int flags = 0;
+
+    for (;;) {
+        struct msghdr msg = {
+            .msg_name = (void *) &nladdr,
+            .msg_namelen = sizeof(nladdr),
+            .msg_iov = &iov,
+            .msg_iovlen = 1
+        };
+
+        ssize_t ret = recvmsg(fd, &msg, flags);
+
+        if (ret < 0) {
+            if (errno == EINTR)
+                continue;
+            perror("recvmsg");
+            return \-1;
+        }
+        if (ret == 0)
+            return 0;
+
+        const struct nlmsghdr *h = (struct nlmsghdr *) buf;
+
+        if (!NLMSG_OK(h, ret)) {
+            fputs("!NLMSG_OK\\n", stderr);
+            return \-1;
+        }
+        for (; NLMSG_OK(h, ret); h = NLMSG_NEXT(h, ret)) {
+            if (h\->nlmsg_type == NLMSG_DONE)
+                return 0;
+            if (h\->nlmsg_type == NLMSG_ERROR) {
+                const struct nlmsgerr *err = NLMSG_DATA(h);
+
+                if (h\->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) {
+                    fputs("NLMSG_ERROR\\n", stderr);
+                } else {
+                    errno = \-err\->error;
+                    perror("NLMSG_ERROR");
+                }
+                return \-1;
+            }
+            if (h\->nlmsg_type != SOCK_DIAG_BY_FAMILY) {
+                fprintf(stderr, "unexpected nlmsg_type %u\\n",
+                        (unsigned) h\->nlmsg_type);
+                return \-1;
+            }
+
+            if (print_diag(NLMSG_DATA(h), h\->nlmsg_len))
+                return \-1;
+        }
+    }
+}
+
+int
+main(void)
+{
+    int fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG);
+
+    if (fd < 0) {
+        perror("socket");
+        return 1;
+    }
+
+    int ret = send_query(fd) || receive_responses(fd);
+
+    close(fd);
+    return ret;
+}
+.fi
 .SH SEE ALSO
 .BR netlink (3),
 .BR rtnetlink (3),
-- 
ldv

--
To unsubscribe from this list: send the line "unsubscribe linux-man" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

  parent reply	other threads:[~2016-03-15 17:26 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
     [not found] <cover.1458040999.git.ldv@altlinux.org>
     [not found] ` <cover.1458040999.git.ldv-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
2016-03-15 17:25   ` [PATCH 1/4] sock_diag.7: New page documenting NETLINK_SOCK_DIAG interface Dmitry V. Levin
     [not found]     ` <20160315172558.GB2903-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
2016-04-04  8:34       ` Michael Kerrisk (man-pages)
     [not found]         ` <57022727.6040606-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-05-18 20:37           ` Michael Kerrisk (man-pages)
     [not found]             ` <0ff8a6f9-6357-7891-de49-ef8e3b8adcb7-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-10-07 14:40               ` Michael Kerrisk (man-pages)
2016-12-07  9:36           ` Dmitry V. Levin
     [not found]             ` <20161207093626.GA23316-u2l5PoMzF/Vg9hUCZPvPmw@public.gmane.org>
2016-12-07 12:56               ` Michael Kerrisk (man-pages)
     [not found]                 ` <9ea0665a-1a9e-0f9e-7fde-cac45f65b0b8-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
2016-12-07 13:59                   ` Dmitry V. Levin
2016-03-15 17:26   ` Dmitry V. Levin [this message]
2016-03-15 17:26   ` [PATCH 3/4] netlink.7: Rename NETLINK_INET_DIAG to NETLINK_SOCK_DIAG Dmitry V. Levin
2016-03-15 17:26   ` [PATCH 4/4] netlink.7: Add references to sock_diag(7) Dmitry V. Levin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20160315172605.GC2903@altlinux.org \
    --to=ldv-u2l5pomzf/vg9huczpvpmw@public.gmane.org \
    --cc=linux-man-u79uwXL29TY76Z2rM5mHXA@public.gmane.org \
    --cc=mtk.manpages-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org \
    --cc=xemul-5HdwGun5lf+gSpxsJD1C4w@public.gmane.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).