blob: 8dd50dba0cf741b135adbf35f9dce6e217e8ad93 [file] [log] [blame]
Dmitry V. Levin38a34c92015-12-17 17:56:48 +00001/*
Dmitry V. Levin285c3f42016-01-06 15:53:45 +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. Levin285c3f42016-01-06 15:53:45 +000028#include "tests.h"
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000029#include <assert.h>
30#include <string.h>
31#include <unistd.h>
32#include <netinet/in.h>
33#include <linux/netlink.h>
34#include <linux/sock_diag.h>
35#include <linux/inet_diag.h>
36
Dmitry V. Levin285c3f42016-01-06 15:53:45 +000037static void
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000038send_query(const int fd, const int family, const int proto)
39{
Dmitry V. Levinaf534b82014-11-21 19:59:16 +000040 struct sockaddr_nl nladdr = {
41 .nl_family = AF_NETLINK
42 };
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000043 struct {
44 struct nlmsghdr nlh;
45 struct inet_diag_req_v2 idr;
Dmitry V. Levinaf534b82014-11-21 19:59:16 +000046 } req = {
47 .nlh = {
48 .nlmsg_len = sizeof(req),
49 .nlmsg_type = SOCK_DIAG_BY_FAMILY,
50 .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
51 },
52 .idr = {
53 .sdiag_family = family,
54 .sdiag_protocol = proto,
55 .idiag_states = -1
56 }
57 };
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000058 struct iovec iov = {
59 .iov_base = &req,
60 .iov_len = sizeof(req)
61 };
62 struct msghdr msg = {
63 .msg_name = (void*)&nladdr,
64 .msg_namelen = sizeof(nladdr),
65 .msg_iov = &iov,
66 .msg_iovlen = 1
67 };
68
Dmitry V. Levin285c3f42016-01-06 15:53:45 +000069 if (sendmsg(fd, &msg, 0) <= 0)
70 perror_msg_and_skip("sendmsg");
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000071}
72
Dmitry V. Levin285c3f42016-01-06 15:53:45 +000073static void
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000074check_responses(const int fd)
75{
76 static char buf[8192];
Dmitry V. Levinaf534b82014-11-21 19:59:16 +000077 struct sockaddr_nl nladdr = {
78 .nl_family = AF_NETLINK
79 };
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000080 struct iovec iov = {
81 .iov_base = buf,
82 .iov_len = sizeof(buf)
83 };
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000084 struct msghdr msg = {
85 .msg_name = (void*)&nladdr,
86 .msg_namelen = sizeof(nladdr),
87 .msg_iov = &iov,
Dmitry V. Levinaf534b82014-11-21 19:59:16 +000088 .msg_iovlen = 1
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000089 };
90
91 ssize_t ret = recvmsg(fd, &msg, 0);
92 if (ret <= 0)
Dmitry V. Levin285c3f42016-01-06 15:53:45 +000093 perror_msg_and_skip("recvmsg");
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +000094
95 struct nlmsghdr *h = (struct nlmsghdr*)buf;
Dmitry V. Levin285c3f42016-01-06 15:53:45 +000096 if (!NLMSG_OK(h, ret))
97 error_msg_and_skip("!NLMSG_OK");
98 if (h->nlmsg_type == NLMSG_ERROR)
99 error_msg_and_skip("NLMSG_ERROR");
100 if (h->nlmsg_type == NLMSG_DONE)
101 error_msg_and_skip("NLMSG_DONE");
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +0000102}
103
104int main(void)
105{
106 struct sockaddr_in addr;
107 socklen_t len = sizeof(addr);
108
109 memset(&addr, 0, sizeof(addr));
110 addr.sin_family = AF_INET;
111 addr.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
112
113 close(0);
114 close(1);
115
Dmitry V. Levin285c3f42016-01-06 15:53:45 +0000116 if (socket(PF_INET, SOCK_STREAM, 0))
117 perror_msg_and_skip("socket PF_INET");
118 if (bind(0, (struct sockaddr *) &addr, len))
119 perror_msg_and_skip("bind");
120 if (listen(0, 5))
121 perror_msg_and_skip("listen");
122 if (socket(AF_NETLINK, SOCK_RAW, NETLINK_INET_DIAG) != 1)
123 perror_msg_and_skip("socket AF_NETLINK");
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +0000124
Dmitry V. Levin285c3f42016-01-06 15:53:45 +0000125 send_query(1, AF_INET, IPPROTO_TCP);
126 check_responses(1);
127 return 0;
Dmitry V. Levinfdfa7222014-09-23 00:14:04 +0000128}