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 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).