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
next prev 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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.