(root)/
strace-6.5/
tests/
nlattr_ifaddrmsg.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  
      11  #include <stdio.h>
      12  #include <arpa/inet.h>
      13  #include "test_nlattr.h"
      14  #include <linux/if_addr.h>
      15  #include <linux/rtnetlink.h>
      16  
      17  #define SET_IFA_FAMILY(af)		\
      18  	do {				\
      19  		ifa_family = af;	\
      20  		ifa_family_str = #af;	\
      21  	}				\
      22  	while (0)
      23  
      24  uint8_t ifa_family;
      25  const char *ifa_family_str;
      26  
      27  static void
      28  init_ifaddrmsg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      29  {
      30  	SET_STRUCT(struct nlmsghdr, nlh,
      31  		.nlmsg_len = msg_len,
      32  		.nlmsg_type = RTM_GETADDR,
      33  		.nlmsg_flags = NLM_F_DUMP
      34  	);
      35  
      36  	struct ifaddrmsg *const msg = NLMSG_DATA(nlh);
      37  	SET_STRUCT(struct ifaddrmsg, msg,
      38  		.ifa_family = ifa_family,
      39  		.ifa_flags = IFA_F_SECONDARY,
      40  		.ifa_scope = RT_SCOPE_UNIVERSE,
      41  		.ifa_index = ifindex_lo()
      42  	);
      43  }
      44  
      45  static void
      46  print_ifaddrmsg(const unsigned int msg_len)
      47  {
      48  	printf("{nlmsg_len=%u, nlmsg_type=RTM_GETADDR, nlmsg_flags=NLM_F_DUMP"
      49  	       ", nlmsg_seq=0, nlmsg_pid=0}, {ifa_family=%s"
      50  	       ", ifa_prefixlen=0"
      51  	       ", ifa_flags=IFA_F_SECONDARY"
      52  	       ", ifa_scope=RT_SCOPE_UNIVERSE"
      53  	       ", ifa_index=" IFINDEX_LO_STR "}",
      54  	       msg_len, ifa_family_str);
      55  }
      56  
      57  int
      58  main(void)
      59  {
      60  	skip_if_unavailable("/proc/self/fd/");
      61  
      62  	static const char address4[] = "12.34.56.78";
      63  	static const char address6[] = "12:34:56:78:90:ab:cd:ef";
      64  	static const struct ifa_cacheinfo ci = {
      65  		.ifa_prefered = 0xabcdefac,
      66  		.ifa_valid = 0xbcdadbca,
      67  		.cstamp = 0xcdabedba,
      68  		.tstamp = 0xdebabdac
      69  	};
      70  
      71  	struct in_addr a4;
      72  	struct in6_addr a6;
      73  	const uint32_t ifa_flags = IFA_F_SECONDARY | IFA_F_PERMANENT;
      74  
      75  	const int fd = create_nl_socket(NETLINK_ROUTE);
      76  	const unsigned int hdrlen = sizeof(struct ifaddrmsg);
      77  	void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
      78  				   NLA_HDRLEN + MAX(sizeof(ci), sizeof(a6)));
      79  
      80  	static char pattern[4096];
      81  	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
      82  
      83  	SET_IFA_FAMILY(AF_UNSPEC);
      84  	const unsigned int nla_type = 0xffff & NLA_TYPE_MASK;
      85  	char nla_type_str[256];
      86  	sprintf(nla_type_str, "%#x /* IFA_??? */", nla_type);
      87  	TEST_NLATTR_(fd, nlh0, hdrlen,
      88  		     init_ifaddrmsg, print_ifaddrmsg,
      89  		     nla_type, nla_type_str,
      90  		     4, pattern, 4,
      91  		     print_quoted_hex(pattern, 4));
      92  
      93  	TEST_NLATTR(fd, nlh0, hdrlen,
      94  		    init_ifaddrmsg, print_ifaddrmsg,
      95  		    IFA_ADDRESS, 4, pattern, 4,
      96  		    print_quoted_hex(pattern, 4));
      97  
      98  	SET_IFA_FAMILY(AF_INET);
      99  
     100  	if (!inet_pton(AF_INET, address4, &a4))
     101  		perror_msg_and_skip("inet_pton");
     102  
     103  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     104  			   init_ifaddrmsg, print_ifaddrmsg,
     105  			   IFA_ADDRESS, pattern, a4,
     106  			   printf("inet_addr(\"%s\")", address4));
     107  
     108  	SET_IFA_FAMILY(AF_INET6);
     109  
     110  	if (!inet_pton(AF_INET6, address6, &a6))
     111  		perror_msg_and_skip("inet_pton");
     112  
     113  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     114  			   init_ifaddrmsg, print_ifaddrmsg,
     115  			   IFA_ADDRESS, pattern, a6,
     116  			   printf("inet_pton(AF_INET6, \"%s\")", address6));
     117  
     118  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     119  			   init_ifaddrmsg, print_ifaddrmsg,
     120  			   IFA_CACHEINFO, pattern, ci,
     121  			   printf("{");
     122  			   PRINT_FIELD_U(ci, ifa_prefered);
     123  			   printf(", ");
     124  			   PRINT_FIELD_U(ci, ifa_valid);
     125  			   printf(", ");
     126  			   PRINT_FIELD_U(ci, cstamp);
     127  			   printf(", ");
     128  			   PRINT_FIELD_U(ci, tstamp);
     129  			   printf("}"));
     130  
     131  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     132  			   init_ifaddrmsg, print_ifaddrmsg,
     133  			   IFA_FLAGS, pattern, ifa_flags,
     134  			   printf("IFA_F_SECONDARY|IFA_F_PERMANENT"));
     135  
     136  	puts("+++ exited with 0 +++");
     137  	return 0;
     138  }