(root)/
strace-6.5/
tests-mx32/
netlink_generic.c
       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  }