(root)/
strace-6.5/
tests-mx32/
netlink_kobject_uevent.c
       1  /*
       2   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       3   * Copyright (c) 2017-2021 The strace developers.
       4   * All rights reserved.
       5   *
       6   * SPDX-License-Identifier: GPL-2.0-or-later
       7   */
       8  
       9  #include "tests.h"
      10  #include <string.h>
      11  #include <stdio.h>
      12  #include <sys/socket.h>
      13  #include <arpa/inet.h>
      14  #include "netlink.h"
      15  #include "netlink_kobject_uevent.h"
      16  
      17  static const char *errstr;
      18  
      19  static ssize_t
      20  sys_send(const int fd, const void *const buf, const size_t len)
      21  {
      22  	const ssize_t rc = sendto(fd, buf, len, MSG_DONTWAIT, NULL, 0);
      23  	errstr = sprintrc(rc);
      24  	return rc;
      25  }
      26  
      27  static void
      28  test_nlmsg_type_udev(const int fd)
      29  {
      30  	static const char extra[] = "12345678";
      31  	struct udev_monitor_netlink_header uh = {
      32  		.prefix = "libudev",
      33  		.magic = htonl(0xfeedcafe),
      34  		.header_size = sizeof(uh),
      35  		.properties_off = 40,
      36  		.properties_len = 299,
      37  		.filter_subsystem_hash = htonl(0xc370b302),
      38  		.filter_devtype_hash = htonl(0x10800000),
      39  		.filter_tag_bloom_hi = htonl(0x2000400),
      40  		.filter_tag_bloom_lo = htonl(0x10800000),
      41  	};
      42  	const unsigned int extra_len = LENGTH_OF(extra);
      43  	const unsigned int uh_len = sizeof(uh);
      44  
      45  	char *const buf = tail_alloc(uh_len + extra_len);
      46  	memcpy(buf + extra_len, &uh, uh_len);
      47  
      48  	sys_send(fd, buf + extra_len, uh_len);
      49  	printf("sendto(%d, {prefix=\"%s\", magic=htonl(%#x)"
      50  	       ", header_size=%u, properties_off=%u, properties_len=%u"
      51  	       ", filter_subsystem_hash=htonl(%#x)"
      52  	       ", filter_devtype_hash=htonl(%#x)"
      53  	       ", filter_tag_bloom_hi=htonl(%#x)"
      54  	       ", filter_tag_bloom_lo=htonl(%#x)}, %u, MSG_DONTWAIT, NULL, "
      55  	       "0) = %s\n"
      56  	       , fd, uh.prefix,
      57  	       ntohl(uh.magic), uh.header_size, uh.properties_off,
      58  	       uh.properties_len, ntohl(uh.filter_subsystem_hash),
      59  	       ntohl(uh.filter_devtype_hash), ntohl(uh.filter_tag_bloom_hi),
      60  	       ntohl(uh.filter_tag_bloom_lo), uh_len, errstr);
      61  
      62  	memcpy(buf, &uh, uh_len);
      63  	memcpy(buf + uh_len, extra, extra_len);
      64  	sys_send(fd, buf, uh_len + extra_len);
      65  	printf("sendto(%d, [{prefix=\"%s\", magic=htonl(%#x)"
      66  	       ", header_size=%u, properties_off=%u, properties_len=%u"
      67  	       ", filter_subsystem_hash=htonl(%#x)"
      68  	       ", filter_devtype_hash=htonl(%#x)"
      69  	       ", filter_tag_bloom_hi=htonl(%#x)"
      70  	       ", filter_tag_bloom_lo=htonl(%#x)}, "
      71  	       , fd, uh.prefix,
      72  	       ntohl(uh.magic), uh.header_size, uh.properties_off,
      73  	       uh.properties_len, ntohl(uh.filter_subsystem_hash),
      74  	       ntohl(uh.filter_devtype_hash), ntohl(uh.filter_tag_bloom_hi),
      75  	       ntohl(uh.filter_tag_bloom_lo));
      76  	print_quoted_memory(buf + uh_len, extra_len);
      77  	printf("], %u, MSG_DONTWAIT, NULL, 0) = %s\n",
      78  	       uh_len + extra_len, errstr);
      79  
      80  	memcpy(buf + extra_len + 1, &uh, uh_len - 1);
      81  	sys_send(fd, buf + extra_len + 1, uh_len);
      82  	printf("sendto(%d, ", fd);
      83  	print_quoted_memory(&uh, MIN(uh_len - 1, DEFAULT_STRLEN));
      84  	printf("%s, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
      85  	       (uh_len - 1 > DEFAULT_STRLEN ? "..." : ""),
      86  	       uh_len, errstr);
      87  }
      88  
      89  static void
      90  test_nlmsg_type_kernel(const int fd)
      91  {
      92  	struct udev_monitor_netlink_header uh = {
      93  		.prefix = "change@",
      94  		.magic = htonl(0xfeedcafe),
      95  		.header_size = sizeof(uh),
      96  		.properties_off = 10,
      97  		.properties_len = 299,
      98  		.filter_subsystem_hash = htonl(0xfffffff),
      99  		.filter_devtype_hash = htonl(0x10000000),
     100  		.filter_tag_bloom_hi = htonl(0x2000400),
     101  	};
     102  	const unsigned int uh_len = sizeof(uh);
     103  
     104  	TAIL_ALLOC_OBJECT_CONST_PTR(struct udev_monitor_netlink_header, p);
     105  	memcpy(p, &uh, uh_len);
     106  
     107  	sys_send(fd, p, uh_len);
     108  	printf("sendto(%d, ", fd);
     109  	print_quoted_memory(&uh, MIN(uh_len, DEFAULT_STRLEN));
     110  	printf("%s, %u, MSG_DONTWAIT, NULL, 0) = %s\n",
     111  	       (uh_len > DEFAULT_STRLEN ? "..." : ""),
     112  	       uh_len, errstr);
     113  }
     114  
     115  int
     116  main(void)
     117  {
     118  	skip_if_unavailable("/proc/self/fd/");
     119  
     120  	int fd = create_nl_socket(NETLINK_KOBJECT_UEVENT);
     121  
     122  	test_nlmsg_type_udev(fd);
     123  	test_nlmsg_type_kernel(fd);
     124  	/* test using data that looks like a zero-length C string */
     125  	char *const buf = tail_alloc(DEFAULT_STRLEN + 1);
     126  	buf[0] = '=';
     127  	fill_memory_ex(buf + 1, DEFAULT_STRLEN, 0, DEFAULT_STRLEN);
     128  
     129  	sys_send(fd, buf + 1, DEFAULT_STRLEN);
     130  	printf("sendto(%d, ", fd);
     131  	print_quoted_memory(buf + 1, DEFAULT_STRLEN);
     132  	printf(", %u, MSG_DONTWAIT, NULL, 0) = %s\n",
     133  	       DEFAULT_STRLEN, errstr);
     134  
     135  	sys_send(fd, buf, DEFAULT_STRLEN + 1);
     136  	printf("sendto(%d, ", fd);
     137  	print_quoted_memory(buf, DEFAULT_STRLEN);
     138  	printf("..., %u, MSG_DONTWAIT, NULL, 0) = %s\n",
     139  	       DEFAULT_STRLEN + 1, errstr);
     140  
     141  	puts("+++ exited with 0 +++");
     142  	return 0;
     143  }