blob: 6e3b63b2e57c8202fa2c18ecddfdf87b9bdec9ca [file] [log] [blame]
Dmitry V. Levin38a34c92015-12-17 17:56:48 +00001/*
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +00002 * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org>
Dmitry V. Levin38a34c92015-12-17 17:56:48 +00003 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. The name of the author may not be used to endorse or promote products
14 * derived from this software without specific prior written permission.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +000028#include "tests.h"
Dmitry V. Levin6b5df322014-12-25 00:11:40 +000029#include <assert.h>
30#include <stddef.h>
Dmitry V. Levinb6535092015-01-08 22:29:12 +000031#include <stdint.h>
Dmitry V. Levin6b5df322014-12-25 00:11:40 +000032#include <string.h>
33#include <unistd.h>
34#include <sys/socket.h>
35#include <sys/un.h>
36#include <linux/netlink.h>
37#include <linux/sock_diag.h>
38#include <linux/unix_diag.h>
39
Dmitry V. Levind9f7e7a2015-01-09 03:03:39 +000040#if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG
41# define NETLINK_SOCK_DIAG NETLINK_INET_DIAG
42#endif
43
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +000044static void
Dmitry V. Levin6b5df322014-12-25 00:11:40 +000045send_query(const int fd, const int family, const int proto)
46{
47 struct sockaddr_nl nladdr = {
48 .nl_family = AF_NETLINK
49 };
50 struct {
51 struct nlmsghdr nlh;
52 struct unix_diag_req udr;
53 } req = {
54 .nlh = {
55 .nlmsg_len = sizeof(req),
56 .nlmsg_type = SOCK_DIAG_BY_FAMILY,
57 .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
58 },
59 .udr = {
60 .sdiag_family = family,
61 .sdiag_protocol = proto,
62 .udiag_states = -1,
63 .udiag_show = UDIAG_SHOW_NAME | UDIAG_SHOW_PEER
64 }
65 };
66 struct iovec iov = {
67 .iov_base = &req,
68 .iov_len = sizeof(req)
69 };
70 struct msghdr msg = {
71 .msg_name = (void*)&nladdr,
72 .msg_namelen = sizeof(nladdr),
73 .msg_iov = &iov,
74 .msg_iovlen = 1
75 };
76
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +000077 if (sendmsg(fd, &msg, 0) <= 0)
78 perror_msg_and_skip("sendmsg");
Dmitry V. Levin6b5df322014-12-25 00:11:40 +000079}
80
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +000081static void
Dmitry V. Levin6b5df322014-12-25 00:11:40 +000082check_responses(const int fd)
83{
84 static char buf[8192];
85 struct sockaddr_nl nladdr = {
86 .nl_family = AF_NETLINK
87 };
88 struct iovec iov = {
89 .iov_base = buf,
90 .iov_len = sizeof(buf)
91 };
92 struct msghdr msg = {
93 .msg_name = (void*)&nladdr,
94 .msg_namelen = sizeof(nladdr),
95 .msg_iov = &iov,
96 .msg_iovlen = 1
97 };
98
99 ssize_t ret = recvmsg(fd, &msg, 0);
100 if (ret <= 0)
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +0000101 perror_msg_and_skip("recvmsg");
Dmitry V. Levin6b5df322014-12-25 00:11:40 +0000102
103 struct nlmsghdr *h = (struct nlmsghdr*)buf;
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +0000104 if (!NLMSG_OK(h, ret))
105 error_msg_and_skip("!NLMSG_OK");
106 if (h->nlmsg_type == NLMSG_ERROR)
107 error_msg_and_skip("NLMSG_ERROR");
108 if (h->nlmsg_type == NLMSG_DONE)
109 error_msg_and_skip("NLMSG_DONE");
Dmitry V. Levin6b5df322014-12-25 00:11:40 +0000110}
111
112#define SUN_PATH "netlink_unix_diag_socket"
113int main(void)
114{
115 struct sockaddr_un addr = {
116 .sun_family = AF_UNIX,
117 .sun_path = SUN_PATH
118 };
119 socklen_t len = offsetof(struct sockaddr_un, sun_path) + sizeof(SUN_PATH);
120
121 close(0);
122 close(1);
123
124 (void) unlink(SUN_PATH);
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +0000125 if (socket(PF_LOCAL, SOCK_STREAM, 0))
126 perror_msg_and_skip("socket PF_LOCAL");
127 if (bind(0, (struct sockaddr *) &addr, len))
128 perror_msg_and_skip("bind");
129 if (listen(0, 5))
130 perror_msg_and_skip("listen");
Dmitry V. Levin6add1b02015-03-18 20:18:27 +0000131
Dmitry V. Levin6b5df322014-12-25 00:11:40 +0000132 assert(unlink(SUN_PATH) == 0);
133
134 if (socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG) != 1)
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +0000135 perror_msg_and_skip("socket AF_NETLINK");
Dmitry V. Levin6b5df322014-12-25 00:11:40 +0000136
Dmitry V. Levinea56b5b2016-01-06 15:55:12 +0000137 send_query(1, AF_UNIX, 0);
138 check_responses(1);
139 return 0;
Dmitry V. Levin6b5df322014-12-25 00:11:40 +0000140}