(root)/
strace-6.5/
tests-mx32/
nlattr_ifla_protinfo.c
       1  /*
       2   * Check decoding of IFLA_PROTINFO netlink attribute.
       3   *
       4   * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com>
       5   * Copyright (c) 2021 Eugene Syromyatnikov <evgsyr@gmail.com>
       6   * Copyright (c) 2017-2021 The strace developers.
       7   * All rights reserved.
       8   *
       9   * SPDX-License-Identifier: GPL-2.0-or-later
      10   */
      11  
      12  #include "tests.h"
      13  
      14  #include <inttypes.h>
      15  #include <netinet/in.h>
      16  #include <linux/if_arp.h>
      17  #include <linux/if_link.h>
      18  #include <linux/rtnetlink.h>
      19  #include <stdio.h>
      20  
      21  #include "test_nlattr.h"
      22  
      23  #include "xlat.h"
      24  #include "xlat/addrfams.h"
      25  
      26  #include "nlattr_ifla_af_inet6.h"
      27  
      28  static const unsigned int hdrlen = sizeof(struct ifinfomsg);
      29  
      30  static uint16_t af;
      31  static const char *af_str;
      32  
      33  static void
      34  init_ifinfomsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      35  {
      36  	SET_STRUCT(struct nlmsghdr, nlh,
      37  		.nlmsg_len = msg_len,
      38  		.nlmsg_type = RTM_GETLINK,
      39  		.nlmsg_flags = NLM_F_DUMP
      40  	);
      41  
      42  	struct ifinfomsg *const msg = NLMSG_DATA(nlh);
      43  	SET_STRUCT(struct ifinfomsg, msg,
      44  		.ifi_family = af,
      45  		.ifi_type = ARPHRD_LOOPBACK,
      46  		.ifi_index = ifindex_lo(),
      47  		.ifi_flags = IFF_UP,
      48  	);
      49  }
      50  
      51  static void
      52  init_ifinfomsg_protinfo(struct nlmsghdr *const nlh, const unsigned int msg_len)
      53  {
      54  	init_ifinfomsg(nlh, msg_len);
      55  
      56  	struct nlattr *const nla = NLMSG_ATTR(nlh, sizeof(struct ifinfomsg));
      57  	SET_STRUCT(struct nlattr, nla,
      58  		.nla_len = msg_len - NLMSG_SPACE(hdrlen),
      59  		.nla_type = IFLA_PROTINFO,
      60  	);
      61  }
      62  
      63  static void
      64  print_ifinfomsg(const unsigned int msg_len)
      65  {
      66  	printf("{nlmsg_len=%u, nlmsg_type=" XLAT_FMT ", nlmsg_flags=" XLAT_FMT
      67  	       ", nlmsg_seq=0, nlmsg_pid=0}, {ifi_family=%s"
      68  	       ", ifi_type=" XLAT_FMT ", ifi_index=" XLAT_FMT_U
      69  	       ", ifi_flags=" XLAT_FMT ", ifi_change=0}",
      70  	       msg_len, XLAT_ARGS(RTM_GETLINK), XLAT_ARGS(NLM_F_DUMP),
      71  	       af_str, XLAT_ARGS(ARPHRD_LOOPBACK),
      72  	       XLAT_SEL(ifindex_lo(), IFINDEX_LO_STR), XLAT_ARGS(IFF_UP));
      73  }
      74  
      75  static void
      76  print_ifinfomsg_protinfo(const unsigned int msg_len)
      77  {
      78  	print_ifinfomsg(msg_len);
      79  	printf(", [{nla_len=%u, nla_type=" XLAT_FMT "}",
      80  	       msg_len - NLMSG_SPACE(hdrlen), XLAT_ARGS(IFLA_PROTINFO));
      81  }
      82  
      83  int
      84  main(void)
      85  {
      86  	skip_if_unavailable("/proc/self/fd/");
      87  
      88  	const int fd = create_nl_socket(NETLINK_ROUTE);
      89  	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
      90  				   NLA_HDRLEN * 2 + 42);
      91  
      92  	static char buf[256];
      93  	fill_memory_ex(buf, sizeof(buf), 32, 224);
      94  
      95  	/* Unsupported address families */
      96  	static const uint8_t skip_af[] = { AF_BRIDGE, AF_INET6 };
      97  	size_t pos = 0;
      98  	for (size_t i = 0; i < 256; i++) {
      99  		if (i == skip_af[pos]) {
     100  			pos += 1;
     101  			continue;
     102  		}
     103  
     104  		af = i;
     105  		af_str = sprintxval(addrfams, i, "AF_???");
     106  		TEST_NLATTR_(fd, nlh0, hdrlen, init_ifinfomsg, print_ifinfomsg,
     107  			     IFLA_PROTINFO, XLAT_STR(IFLA_PROTINFO),
     108  			     42, buf, 42,
     109  			     print_quoted_hex(buf, 32);
     110  			     printf("..."));
     111  	}
     112  
     113  	/* AF_BRIDGE is handled by nlattr_ifla_brport */
     114  
     115  	/* AF_INET6 */
     116  	static char af_inet6_str[20];
     117  	af = AF_INET6;
     118  	snprintf(af_inet6_str, sizeof(af_inet6_str), XLAT_FMT,
     119  		 XLAT_ARGS(AF_INET6));
     120  	af_str = af_inet6_str;
     121  	check_ifla_af_inet6(fd, nlh0, hdrlen,
     122  			    init_ifinfomsg_protinfo, print_ifinfomsg_protinfo,
     123  			    buf, 1);
     124  
     125  	puts("+++ exited with 0 +++");
     126  	return 0;
     127  }