128e955d747661fd0f437e70f41e477c9161467dfFabien Siron/* 228e955d747661fd0f437e70f41e477c9161467dfFabien Siron * This file is part of net-yy-netlink strace test. 328e955d747661fd0f437e70f41e477c9161467dfFabien Siron * 428e955d747661fd0f437e70f41e477c9161467dfFabien Siron * Copyright (c) 2014-2016 Dmitry V. Levin <ldv@altlinux.org> 528e955d747661fd0f437e70f41e477c9161467dfFabien Siron * Copyright (c) 2016 Fabien Siron <fabien.siron@epita.fr> 628e955d747661fd0f437e70f41e477c9161467dfFabien Siron * All rights reserved. 728e955d747661fd0f437e70f41e477c9161467dfFabien Siron * 828e955d747661fd0f437e70f41e477c9161467dfFabien Siron * Redistribution and use in source and binary forms, with or without 928e955d747661fd0f437e70f41e477c9161467dfFabien Siron * modification, are permitted provided that the following conditions 1028e955d747661fd0f437e70f41e477c9161467dfFabien Siron * are met: 1128e955d747661fd0f437e70f41e477c9161467dfFabien Siron * 1. Redistributions of source code must retain the above copyright 1228e955d747661fd0f437e70f41e477c9161467dfFabien Siron * notice, this list of conditions and the following disclaimer. 1328e955d747661fd0f437e70f41e477c9161467dfFabien Siron * 2. Redistributions in binary form must reproduce the above copyright 1428e955d747661fd0f437e70f41e477c9161467dfFabien Siron * notice, this list of conditions and the following disclaimer in the 1528e955d747661fd0f437e70f41e477c9161467dfFabien Siron * documentation and/or other materials provided with the distribution. 1628e955d747661fd0f437e70f41e477c9161467dfFabien Siron * 3. The name of the author may not be used to endorse or promote products 1728e955d747661fd0f437e70f41e477c9161467dfFabien Siron * derived from this software without specific prior written permission. 1828e955d747661fd0f437e70f41e477c9161467dfFabien Siron * 1928e955d747661fd0f437e70f41e477c9161467dfFabien Siron * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 2028e955d747661fd0f437e70f41e477c9161467dfFabien Siron * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 2128e955d747661fd0f437e70f41e477c9161467dfFabien Siron * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 2228e955d747661fd0f437e70f41e477c9161467dfFabien Siron * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 2328e955d747661fd0f437e70f41e477c9161467dfFabien Siron * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 2428e955d747661fd0f437e70f41e477c9161467dfFabien Siron * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 2528e955d747661fd0f437e70f41e477c9161467dfFabien Siron * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 2628e955d747661fd0f437e70f41e477c9161467dfFabien Siron * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 2728e955d747661fd0f437e70f41e477c9161467dfFabien Siron * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 2828e955d747661fd0f437e70f41e477c9161467dfFabien Siron * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 2928e955d747661fd0f437e70f41e477c9161467dfFabien Siron */ 3028e955d747661fd0f437e70f41e477c9161467dfFabien Siron 3128e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include "tests.h" 3228e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include <errno.h> 3328e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include <string.h> 3428e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include <unistd.h> 3528e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include <netinet/in.h> 3628e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include <linux/netlink.h> 3728e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include <linux/sock_diag.h> 3828e955d747661fd0f437e70f41e477c9161467dfFabien Siron#include <linux/netlink_diag.h> 3928e955d747661fd0f437e70f41e477c9161467dfFabien Siron 4028e955d747661fd0f437e70f41e477c9161467dfFabien Siron#if !defined NETLINK_SOCK_DIAG && defined NETLINK_INET_DIAG 4128e955d747661fd0f437e70f41e477c9161467dfFabien Siron# define NETLINK_SOCK_DIAG NETLINK_INET_DIAG 4228e955d747661fd0f437e70f41e477c9161467dfFabien Siron#endif 4328e955d747661fd0f437e70f41e477c9161467dfFabien Siron 4428e955d747661fd0f437e70f41e477c9161467dfFabien Sironstatic void 4528e955d747661fd0f437e70f41e477c9161467dfFabien Sironsend_query(const int fd) 4628e955d747661fd0f437e70f41e477c9161467dfFabien Siron{ 4728e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct sockaddr_nl nladdr = { 4828e955d747661fd0f437e70f41e477c9161467dfFabien Siron .nl_family = AF_NETLINK 4928e955d747661fd0f437e70f41e477c9161467dfFabien Siron }; 5028e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct { 5128e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct nlmsghdr nlh; 5228e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct netlink_diag_req ndr; 5328e955d747661fd0f437e70f41e477c9161467dfFabien Siron } req = { 5428e955d747661fd0f437e70f41e477c9161467dfFabien Siron .nlh = { 5528e955d747661fd0f437e70f41e477c9161467dfFabien Siron .nlmsg_len = sizeof(req), 5628e955d747661fd0f437e70f41e477c9161467dfFabien Siron .nlmsg_type = SOCK_DIAG_BY_FAMILY, 5728e955d747661fd0f437e70f41e477c9161467dfFabien Siron .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST 5828e955d747661fd0f437e70f41e477c9161467dfFabien Siron }, 5928e955d747661fd0f437e70f41e477c9161467dfFabien Siron .ndr = { 6028e955d747661fd0f437e70f41e477c9161467dfFabien Siron .sdiag_family = AF_NETLINK, 6128e955d747661fd0f437e70f41e477c9161467dfFabien Siron .sdiag_protocol = NDIAG_PROTO_ALL, 6228e955d747661fd0f437e70f41e477c9161467dfFabien Siron .ndiag_show = NDIAG_SHOW_MEMINFO 6328e955d747661fd0f437e70f41e477c9161467dfFabien Siron } 6428e955d747661fd0f437e70f41e477c9161467dfFabien Siron }; 6528e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct iovec iov = { 6628e955d747661fd0f437e70f41e477c9161467dfFabien Siron .iov_base = &req, 6728e955d747661fd0f437e70f41e477c9161467dfFabien Siron .iov_len = sizeof(req) 6828e955d747661fd0f437e70f41e477c9161467dfFabien Siron }; 6928e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct msghdr msg = { 7028e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_name = (void *) &nladdr, 7128e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_namelen = sizeof(nladdr), 7228e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_iov = &iov, 7328e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_iovlen = 1 7428e955d747661fd0f437e70f41e477c9161467dfFabien Siron }; 7528e955d747661fd0f437e70f41e477c9161467dfFabien Siron 7628e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (sendmsg(fd, &msg, 0) <= 0) 7728e955d747661fd0f437e70f41e477c9161467dfFabien Siron perror_msg_and_skip("sendmsg"); 7828e955d747661fd0f437e70f41e477c9161467dfFabien Siron} 7928e955d747661fd0f437e70f41e477c9161467dfFabien Siron 8028e955d747661fd0f437e70f41e477c9161467dfFabien Sironstatic void 8128e955d747661fd0f437e70f41e477c9161467dfFabien Sironcheck_responses(const int fd) 8228e955d747661fd0f437e70f41e477c9161467dfFabien Siron{ 837b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin static union { 847b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin struct nlmsghdr hdr; 857b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin long buf[8192 / sizeof(long)]; 867b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin } hdr_buf; 877b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin 8828e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct sockaddr_nl nladdr = { 8928e955d747661fd0f437e70f41e477c9161467dfFabien Siron .nl_family = AF_NETLINK 9028e955d747661fd0f437e70f41e477c9161467dfFabien Siron }; 9128e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct iovec iov = { 927b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin .iov_base = hdr_buf.buf, 937b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin .iov_len = sizeof(hdr_buf.buf) 9428e955d747661fd0f437e70f41e477c9161467dfFabien Siron }; 9528e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct msghdr msg = { 9628e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_name = (void *) &nladdr, 9728e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_namelen = sizeof(nladdr), 9828e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_iov = &iov, 9928e955d747661fd0f437e70f41e477c9161467dfFabien Siron .msg_iovlen = 1 10028e955d747661fd0f437e70f41e477c9161467dfFabien Siron }; 10128e955d747661fd0f437e70f41e477c9161467dfFabien Siron 10228e955d747661fd0f437e70f41e477c9161467dfFabien Siron ssize_t ret = recvmsg(fd, &msg, 0); 10328e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (ret <= 0) 10428e955d747661fd0f437e70f41e477c9161467dfFabien Siron perror_msg_and_skip("recvmsg"); 10528e955d747661fd0f437e70f41e477c9161467dfFabien Siron 1067b6979701b5ddda47ba53f82381a5f412708b0adDmitry V. Levin struct nlmsghdr *h = &hdr_buf.hdr; 10728e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (!NLMSG_OK(h, ret)) 10828e955d747661fd0f437e70f41e477c9161467dfFabien Siron error_msg_and_skip("!NLMSG_OK"); 10928e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (h->nlmsg_type == NLMSG_ERROR) { 11028e955d747661fd0f437e70f41e477c9161467dfFabien Siron const struct nlmsgerr *err = NLMSG_DATA(h); 11128e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*err))) 11228e955d747661fd0f437e70f41e477c9161467dfFabien Siron error_msg_and_skip("NLMSG_ERROR"); 11328e955d747661fd0f437e70f41e477c9161467dfFabien Siron errno = -err->error; 11428e955d747661fd0f437e70f41e477c9161467dfFabien Siron perror_msg_and_skip("NLMSG_ERROR"); 11528e955d747661fd0f437e70f41e477c9161467dfFabien Siron } 11628e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (h->nlmsg_type != SOCK_DIAG_BY_FAMILY) 11728e955d747661fd0f437e70f41e477c9161467dfFabien Siron error_msg_and_skip("unexpected nlmsg_type %u", 11828e955d747661fd0f437e70f41e477c9161467dfFabien Siron (unsigned) h->nlmsg_type); 11928e955d747661fd0f437e70f41e477c9161467dfFabien Siron 12028e955d747661fd0f437e70f41e477c9161467dfFabien Siron const struct netlink_diag_msg *diag = NLMSG_DATA(h); 12128e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (h->nlmsg_len < NLMSG_LENGTH(sizeof(*diag))) 12228e955d747661fd0f437e70f41e477c9161467dfFabien Siron error_msg_and_skip("short response"); 12328e955d747661fd0f437e70f41e477c9161467dfFabien Siron} 12428e955d747661fd0f437e70f41e477c9161467dfFabien Siron 12528e955d747661fd0f437e70f41e477c9161467dfFabien Sironint main(void) 12628e955d747661fd0f437e70f41e477c9161467dfFabien Siron{ 12728e955d747661fd0f437e70f41e477c9161467dfFabien Siron struct sockaddr_nl addr; 12828e955d747661fd0f437e70f41e477c9161467dfFabien Siron socklen_t len = sizeof(addr); 12928e955d747661fd0f437e70f41e477c9161467dfFabien Siron 13028e955d747661fd0f437e70f41e477c9161467dfFabien Siron memset(&addr, 0, sizeof(addr)); 13128e955d747661fd0f437e70f41e477c9161467dfFabien Siron addr.nl_family = AF_NETLINK; 13228e955d747661fd0f437e70f41e477c9161467dfFabien Siron 13328e955d747661fd0f437e70f41e477c9161467dfFabien Siron close(0); 13428e955d747661fd0f437e70f41e477c9161467dfFabien Siron close(1); 13528e955d747661fd0f437e70f41e477c9161467dfFabien Siron 13628e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG)) 13728e955d747661fd0f437e70f41e477c9161467dfFabien Siron perror_msg_and_skip("socket AF_NETLINK"); 13828e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (bind(0, (struct sockaddr *) &addr, len)) 13928e955d747661fd0f437e70f41e477c9161467dfFabien Siron perror_msg_and_skip("bind"); 14028e955d747661fd0f437e70f41e477c9161467dfFabien Siron 14128e955d747661fd0f437e70f41e477c9161467dfFabien Siron if (socket(AF_NETLINK, SOCK_RAW, NETLINK_SOCK_DIAG) != 1) 14228e955d747661fd0f437e70f41e477c9161467dfFabien Siron perror_msg_and_skip("socket AF_NETLINK"); 14328e955d747661fd0f437e70f41e477c9161467dfFabien Siron 14428e955d747661fd0f437e70f41e477c9161467dfFabien Siron send_query(1); 14528e955d747661fd0f437e70f41e477c9161467dfFabien Siron check_responses(1); 14628e955d747661fd0f437e70f41e477c9161467dfFabien Siron return 0; 14728e955d747661fd0f437e70f41e477c9161467dfFabien Siron} 148