(root)/
strace-6.5/
tests-m32/
nlattr_smc_diag_msg.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 <sys/socket.h>
      11  
      12  #ifndef AF_SMC
      13  # define AF_SMC 43
      14  #endif
      15  
      16  #include <stdio.h>
      17  #include <string.h>
      18  #include <stdint.h>
      19  #include <arpa/inet.h>
      20  #include "test_nlattr.h"
      21  #include <linux/rtnetlink.h>
      22  #include <linux/smc_diag.h>
      23  #include <linux/sock_diag.h>
      24  
      25  #ifndef SMC_CLNT
      26  # define SMC_CLNT 0
      27  #endif
      28  #ifndef SMC_ACTIVE
      29  # define SMC_ACTIVE 1
      30  #endif
      31  
      32  static const char address[] = "12.34.56.78";
      33  
      34  static void
      35  init_smc_diag_msg(struct nlmsghdr *const nlh, const unsigned int msg_len)
      36  {
      37  	SET_STRUCT(struct nlmsghdr, nlh,
      38  		.nlmsg_len = msg_len,
      39  		.nlmsg_type = SOCK_DIAG_BY_FAMILY,
      40  		.nlmsg_flags = NLM_F_DUMP
      41  	);
      42  
      43  	struct smc_diag_msg *const msg = NLMSG_DATA(nlh);
      44  	SET_STRUCT(struct smc_diag_msg, msg,
      45  		.diag_family = AF_SMC,
      46  		.diag_state = SMC_ACTIVE
      47  	);
      48  
      49  	if (!inet_pton(AF_INET, address, msg->id.idiag_src) ||
      50  	    !inet_pton(AF_INET, address, msg->id.idiag_dst))
      51  		perror_msg_and_skip("inet_pton");
      52  }
      53  
      54  static void
      55  print_smc_diag_msg(const unsigned int msg_len)
      56  {
      57  	printf("{nlmsg_len=%u, nlmsg_type=SOCK_DIAG_BY_FAMILY"
      58  	       ", nlmsg_flags=NLM_F_DUMP, nlmsg_seq=0, nlmsg_pid=0}"
      59  	       ", {diag_family=AF_SMC, diag_state=SMC_ACTIVE"
      60  	       ", diag_fallback=SMC_DIAG_MODE_SMCR, diag_shutdown=0"
      61  	       ", id={idiag_sport=htons(0), idiag_dport=htons(0)"
      62  	       ", idiag_src=inet_addr(\"%s\")"
      63  	       ", idiag_dst=inet_addr(\"%s\")"
      64  	       ", idiag_if=0, idiag_cookie=[0, 0]}"
      65  	       ", diag_uid=0, diag_inode=0}",
      66  	       msg_len, address, address);
      67  }
      68  
      69  #define PRINT_FIELD_SMC_DIAG_CURSOR(where_, field_)		\
      70  	do {							\
      71  		printf("%s=", #field_);				\
      72  		printf("{");					\
      73  		PRINT_FIELD_U((where_).field_, reserved);	\
      74  		printf(", ");					\
      75  		PRINT_FIELD_U((where_).field_, wrap);		\
      76  		printf(", ");					\
      77  		PRINT_FIELD_U((where_).field_, count);		\
      78  		printf("}");					\
      79  	} while (0)
      80  
      81  int main(void)
      82  {
      83  	skip_if_unavailable("/proc/self/fd/");
      84  
      85  	static const struct smc_diag_conninfo cinfo = {
      86  		.token = 0xabcdefac,
      87  		.sndbuf_size = 0xbcdaefad,
      88  		.rmbe_size = 0xcdbaefab,
      89  		.peer_rmbe_size = 0xdbcdedaf,
      90  		.rx_prod = {
      91  			.reserved = 0xabc1,
      92  			.wrap = 0xbca1,
      93  			.count = 0xcdedbad1
      94  		},
      95  		.rx_cons = {
      96  			.reserved = 0xabc2,
      97  			.wrap = 0xbca2,
      98  			.count = 0xcdedbad2
      99  		},
     100  		.tx_prod = {
     101  			.reserved = 0xabc3,
     102  			.wrap = 0xbca3,
     103  			.count = 0xcdedbad3
     104  		},
     105  		.tx_cons = {
     106  			.reserved = 0xabc4,
     107  			.wrap = 0xbca4,
     108  			.count = 0xcdedbad4
     109  		},
     110  		.rx_prod_flags = 0xff,
     111  		.rx_conn_state_flags = 0xff,
     112  		.tx_prod_flags = 0xff,
     113  		.tx_conn_state_flags = 0xff,
     114  		.tx_prep = {
     115  			.reserved = 0xabc5,
     116  			.wrap = 0xbca5,
     117  			.count = 0xcdedbad5
     118  		},
     119  		.tx_sent = {
     120  			.reserved = 0xabc6,
     121  			.wrap = 0xbca6,
     122  			.count = 0xcdedbad6
     123  		},
     124  		.tx_fin = {
     125  			.reserved = 0xabc7,
     126  			.wrap = 0xbca7,
     127  			.count = 0xcdedbad7
     128  		}
     129  	};
     130  	static const struct smc_diag_lgrinfo linfo = {
     131  		.lnk[0] = {
     132  			.link_id = 0xaf,
     133  			.ibport = 0xfa,
     134  			.ibname = "123",
     135  			.gid = "456",
     136  			.peer_gid = "789"
     137  		},
     138  		.role = SMC_CLNT
     139  	};
     140  	static const struct smcd_diag_dmbinfo dinfo = {
     141  		.linkid     = 0xdeadc0de,
     142  		.peer_gid   = 0xbefeededbadc0dedULL,
     143  		.my_gid     = 0xdeec0dedfacebeefULL,
     144  		.token      = 0xcafedecaffeedeedULL,
     145  		.peer_token = 0xfeedfacebeeff00dULL,
     146  	};
     147  	static const struct smc_diag_fallback fb1 = {
     148  		.reason         = 0,
     149  		.peer_diagnosis = 0x03020000,
     150  	};
     151  	static const struct smc_diag_fallback fb2 = {
     152  		.reason         = 0x03060000,
     153  		.peer_diagnosis = 0x99999999,
     154  	};
     155  	static uint8_t sd1 = 0x23;
     156  	static uint8_t sd2 = 0x40;
     157  
     158  	int fd = create_nl_socket(NETLINK_SOCK_DIAG);
     159  	const unsigned int hdrlen = sizeof(struct smc_diag_msg);
     160  	void *const nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen),
     161  					 NLA_HDRLEN +
     162  					 MAX(sizeof(cinfo), sizeof(linfo)));
     163  
     164  	static char pattern[4096];
     165  	fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1);
     166  
     167  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     168  			   init_smc_diag_msg, print_smc_diag_msg,
     169  			   SMC_DIAG_SHUTDOWN, pattern, sd1,
     170  			   printf("RCV_SHUTDOWN|SEND_SHUTDOWN|0x20"));
     171  
     172  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     173  			   init_smc_diag_msg, print_smc_diag_msg,
     174  			   SMC_DIAG_SHUTDOWN, pattern, sd2,
     175  			   printf("0x40 /* ???_SHUTDOWN */"));
     176  
     177  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     178  			   init_smc_diag_msg, print_smc_diag_msg,
     179  			   SMC_DIAG_CONNINFO, pattern, cinfo,
     180  			   printf("{");
     181  			   PRINT_FIELD_U(cinfo, token);
     182  			   printf(", ");
     183  			   PRINT_FIELD_U(cinfo, sndbuf_size);
     184  			   printf(", ");
     185  			   PRINT_FIELD_U(cinfo, rmbe_size);
     186  			   printf(", ");
     187  			   PRINT_FIELD_U(cinfo, peer_rmbe_size);
     188  			   printf(", ");
     189  			   PRINT_FIELD_SMC_DIAG_CURSOR(cinfo, rx_prod);
     190  			   printf(", ");
     191  			   PRINT_FIELD_SMC_DIAG_CURSOR(cinfo, rx_cons);
     192  			   printf(", ");
     193  			   PRINT_FIELD_SMC_DIAG_CURSOR(cinfo, tx_prod);
     194  			   printf(", ");
     195  			   PRINT_FIELD_SMC_DIAG_CURSOR(cinfo, tx_cons);
     196  			   printf(", rx_prod_flags=0xff");
     197  			   printf(", rx_conn_state_flags=0xff");
     198  			   printf(", tx_prod_flags=0xff");
     199  			   printf(", tx_conn_state_flags=0xff");
     200  			   printf(", ");
     201  			   PRINT_FIELD_SMC_DIAG_CURSOR(cinfo, tx_prep);
     202  			   printf(", ");
     203  			   PRINT_FIELD_SMC_DIAG_CURSOR(cinfo, tx_sent);
     204  			   printf(", ");
     205  			   PRINT_FIELD_SMC_DIAG_CURSOR(cinfo, tx_fin);
     206  			   printf("}"));
     207  
     208  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     209  			   init_smc_diag_msg, print_smc_diag_msg,
     210  			   SMC_DIAG_LGRINFO, pattern, linfo,
     211  			   printf("{lnk=[{");
     212  			   PRINT_FIELD_U(linfo.lnk[0], link_id);
     213  			   printf(", ibname=\"%s\"", linfo.lnk[0].ibname);
     214  			   printf(", ");
     215  			   PRINT_FIELD_U(linfo.lnk[0], ibport);
     216  			   printf(", gid=\"%s\"", linfo.lnk[0].gid);
     217  			   printf(", peer_gid=\"%s\"}]", linfo.lnk[0].peer_gid);
     218  			   printf(", role=SMC_CLNT}"));
     219  
     220  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     221  			   init_smc_diag_msg, print_smc_diag_msg,
     222  			   SMC_DIAG_DMBINFO, pattern, dinfo,
     223  			   printf("{");
     224  			   PRINT_FIELD_U(dinfo, linkid);
     225  			   printf(", ");
     226  			   PRINT_FIELD_X(dinfo, peer_gid);
     227  			   printf(", ");
     228  			   PRINT_FIELD_X(dinfo, my_gid);
     229  			   printf(", ");
     230  			   PRINT_FIELD_X(dinfo, token);
     231  			   printf(", ");
     232  			   PRINT_FIELD_X(dinfo, peer_token);
     233  			   printf("}"));
     234  
     235  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     236  			   init_smc_diag_msg, print_smc_diag_msg,
     237  			   SMC_DIAG_FALLBACK, pattern, fb1,
     238  			   printf("{reason=0 /* SMC_CLC_DECL_??? */");
     239  			   printf(", peer_diagnosis=0x3020000"
     240  			          " /* SMC_CLC_DECL_IPSEC */}"));
     241  
     242  	TEST_NLATTR_OBJECT(fd, nlh0, hdrlen,
     243  			   init_smc_diag_msg, print_smc_diag_msg,
     244  			   SMC_DIAG_FALLBACK, pattern, fb2,
     245  			   printf("{reason=0x3060000"
     246  			          " /* SMC_CLC_DECL_OPTUNSUPP */");
     247  			   printf(", peer_diagnosis=0x99999999"
     248  			          " /* SMC_CLC_DECL_??? */}"));
     249  
     250  	printf("+++ exited with 0 +++\n");
     251  	return 0;
     252  }