1 /*
2 * Copyright (c) 2017-2023 The strace developers.
3 *
4 * SPDX-License-Identifier: GPL-2.0-or-later
5 */
6
7 /* This test case is based on netlink_selinux.c */
8
9 #include "tests.h"
10
11 #include <stdio.h>
12 #include <string.h>
13 #include <unistd.h>
14 #include <sys/socket.h>
15 #include "netlink.h"
16 #include <linux/genetlink.h>
17
18 static void
19 test_nlmsg_type(const int fd)
20 {
21 /*
22 * Though GENL_ID_CTRL number is statically fixed in this test case,
23 * strace does not have a builtin knowledge that the corresponding
24 * string is "nlctrl".
25 */
26 long rc;
27 struct {
28 const struct nlmsghdr nlh;
29 struct genlmsghdr gnlh;
30 } req = {
31 .nlh = {
32 .nlmsg_len = sizeof(req),
33 .nlmsg_type = GENL_ID_CTRL,
34 .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
35 },
36 .gnlh = {
37 .cmd = CTRL_CMD_GETFAMILY
38 }
39 };
40
41 rc = sendto(fd, &req, sizeof(req), MSG_DONTWAIT, NULL, 0);
42 printf("sendto(%d, [{nlmsg_len=%u, nlmsg_type=nlctrl"
43 ", nlmsg_flags=NLM_F_REQUEST|0x300, nlmsg_seq=0, nlmsg_pid=0}"
44 ", \"\\x03\\x00\\x00\\x00\"], %u"
45 ", MSG_DONTWAIT, NULL, 0) = %s\n",
46 fd, req.nlh.nlmsg_len,
47 (unsigned int) sizeof(req), sprintrc(rc));
48 }
49
50 static void
51 test_sendmsg_nlmsg_type(const int fd)
52 {
53 /*
54 * Though GENL_ID_CTRL number is statically fixed in this test case,
55 * strace does not have a builtin knowledge that the corresponding
56 * string is "nlctrl".
57 */
58 long rc;
59 struct {
60 const struct nlmsghdr nlh;
61 struct genlmsghdr gnlh;
62 } req = {
63 .nlh = {
64 .nlmsg_len = sizeof(req),
65 .nlmsg_type = GENL_ID_CTRL,
66 .nlmsg_flags = NLM_F_DUMP | NLM_F_REQUEST
67 },
68 .gnlh = {
69 .cmd = CTRL_CMD_GETFAMILY
70 }
71 };
72
73 struct iovec iov[1] = {
74 { .iov_base = &req, .iov_len = sizeof(req) }
75 };
76 struct msghdr msg = {
77 .msg_iov = iov,
78 .msg_iovlen = 1
79 };
80
81 rc = sendmsg(fd, &msg, MSG_DONTWAIT);
82 printf("sendmsg(%d, {msg_name=NULL, msg_namelen=0"
83 ", msg_iov=[{iov_base=[{nlmsg_len=%u, nlmsg_type=nlctrl"
84 ", nlmsg_flags=NLM_F_REQUEST|0x300, nlmsg_seq=0, nlmsg_pid=0}"
85 ", \"\\x03\\x00\\x00\\x00\"], iov_len=%u}], msg_iovlen=1"
86 ", msg_controllen=0, msg_flags=0}, MSG_DONTWAIT) = %s\n",
87 fd, req.nlh.nlmsg_len, (unsigned int) iov[0].iov_len,
88 sprintrc(rc));
89 }
90
91 int main(void)
92 {
93 skip_if_unavailable("/proc/self/fd/");
94
95 int fd = create_nl_socket(NETLINK_GENERIC);
96
97 test_nlmsg_type(fd);
98 test_sendmsg_nlmsg_type(fd);
99
100 printf("+++ exited with 0 +++\n");
101
102 return 0;
103 }