1 /* 2 * Copyright (c) 2017 JingPiao Chen <chenjingpiao@gmail.com> 3 * Copyright (c) 2017 The strace developers. 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. The name of the author may not be used to endorse or promote products 15 * derived from this software without specific prior written permission. 16 * 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 27 */ 28 29 #include "tests.h" 30 #include <sys/socket.h> 31 32 #ifdef AF_SMC 33 34 # include <stdio.h> 35 # include <string.h> 36 # include <stdint.h> 37 # include <arpa/inet.h> 38 # include "test_nlattr.h" 39 # include <linux/rtnetlink.h> 40 # include <linux/smc_diag.h> 41 # include <linux/sock_diag.h> 42 43 # ifndef SMC_CLNT 44 # define SMC_CLNT 0 45 # endif 46 # ifndef SMC_ACTIVE 47 # define SMC_ACTIVE 1 48 # endif 49 50 static const char address[] = "12.34.56.78"; 51 52 static void 53 init_smc_diag_msg(struct nlmsghdr *const nlh, const unsigned int msg_len) 54 { 55 SET_STRUCT(struct nlmsghdr, nlh, 56 .nlmsg_len = msg_len, 57 .nlmsg_type = SOCK_DIAG_BY_FAMILY, 58 .nlmsg_flags = NLM_F_DUMP 59 ); 60 61 struct smc_diag_msg *const msg = NLMSG_DATA(nlh); 62 SET_STRUCT(struct smc_diag_msg, msg, 63 .diag_family = AF_SMC, 64 .diag_state = SMC_ACTIVE 65 ); 66 67 if (!inet_pton(AF_INET, address, msg->id.idiag_src) || 68 !inet_pton(AF_INET, address, msg->id.idiag_dst)) 69 perror_msg_and_skip("inet_pton"); 70 } 71 72 static void 73 print_smc_diag_msg(const unsigned int msg_len) 74 { 75 printf("{len=%u, type=SOCK_DIAG_BY_FAMILY" 76 ", flags=NLM_F_DUMP, seq=0, pid=0}" 77 ", {diag_family=AF_SMC, diag_state=SMC_ACTIVE" 78 ", diag_fallback=0, diag_shutdown=0" 79 ", id={idiag_sport=htons(0), idiag_dport=htons(0)" 80 ", idiag_src=inet_addr(\"%s\")" 81 ", idiag_dst=inet_addr(\"%s\")" 82 ", idiag_if=0, idiag_cookie=[0, 0]}" 83 ", diag_uid=0, diag_inode=0}", 84 msg_len, address, address); 85 } 86 87 #define PRINT_FIELD_SMC_DIAG_CURSOR(prefix_, where_, field_) \ 88 do { \ 89 printf("%s%s=", (prefix_), #field_); \ 90 PRINT_FIELD_U("{", (where_).field_, reserved); \ 91 PRINT_FIELD_U(", ", (where_).field_, wrap); \ 92 PRINT_FIELD_U(", ", (where_).field_, count); \ 93 printf("}"); \ 94 } while (0) 95 96 int main(void) 97 { 98 skip_if_unavailable("/proc/self/fd/"); 99 100 int fd = create_nl_socket(NETLINK_SOCK_DIAG); 101 const unsigned int hdrlen = sizeof(struct smc_diag_msg); 102 void *const nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); 103 104 static char pattern[4096]; 105 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1); 106 107 static const struct smc_diag_conninfo cinfo = { 108 .token = 0xabcdefac, 109 .sndbuf_size = 0xbcdaefad, 110 .rmbe_size = 0xcdbaefab, 111 .peer_rmbe_size = 0xdbcdedaf, 112 .rx_prod = { 113 .reserved = 0xabc1, 114 .wrap = 0xbca1, 115 .count = 0xcdedbad1 116 }, 117 .rx_cons = { 118 .reserved = 0xabc2, 119 .wrap = 0xbca2, 120 .count = 0xcdedbad2 121 }, 122 .tx_prod = { 123 .reserved = 0xabc3, 124 .wrap = 0xbca3, 125 .count = 0xcdedbad3 126 }, 127 .tx_cons = { 128 .reserved = 0xabc4, 129 .wrap = 0xbca4, 130 .count = 0xcdedbad4 131 }, 132 .rx_prod_flags = 0xff, 133 .rx_conn_state_flags = 0xff, 134 .tx_prod_flags = 0xff, 135 .tx_conn_state_flags = 0xff, 136 .tx_prep = { 137 .reserved = 0xabc5, 138 .wrap = 0xbca5, 139 .count = 0xcdedbad5 140 }, 141 .tx_sent = { 142 .reserved = 0xabc6, 143 .wrap = 0xbca6, 144 .count = 0xcdedbad6 145 }, 146 .tx_fin = { 147 .reserved = 0xabc7, 148 .wrap = 0xbca7, 149 .count = 0xcdedbad7 150 } 151 }; 152 153 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 154 init_smc_diag_msg, print_smc_diag_msg, 155 SMC_DIAG_CONNINFO, pattern, cinfo, 156 PRINT_FIELD_U("{", cinfo, token); 157 PRINT_FIELD_U(", ", cinfo, sndbuf_size); 158 PRINT_FIELD_U(", ", cinfo, rmbe_size); 159 PRINT_FIELD_U(", ", cinfo, peer_rmbe_size); 160 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, rx_prod); 161 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, rx_cons); 162 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_prod); 163 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_cons); 164 printf(", rx_prod_flags=0xff"); 165 printf(", rx_conn_state_flags=0xff"); 166 printf(", tx_prod_flags=0xff"); 167 printf(", tx_conn_state_flags=0xff"); 168 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_prep); 169 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_sent); 170 PRINT_FIELD_SMC_DIAG_CURSOR(", ", cinfo, tx_fin); 171 printf("}")); 172 173 static const struct smc_diag_lgrinfo linfo = { 174 .lnk[0] = { 175 .link_id = 0xaf, 176 .ibport = 0xfa, 177 .ibname = "123", 178 .gid = "456", 179 .peer_gid = "789" 180 }, 181 .role = SMC_CLNT 182 }; 183 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 184 init_smc_diag_msg, print_smc_diag_msg, 185 SMC_DIAG_LGRINFO, pattern, linfo, 186 PRINT_FIELD_U("{lnk[0]={", linfo.lnk[0], link_id); 187 printf(", ibname=\"%s\"", linfo.lnk[0].ibname); 188 PRINT_FIELD_U(", ", linfo.lnk[0], ibport); 189 printf(", gid=\"%s\"", linfo.lnk[0].gid); 190 printf(", peer_gid=\"%s\"}", linfo.lnk[0].peer_gid); 191 printf(", role=SMC_CLNT}")); 192 193 printf("+++ exited with 0 +++\n"); 194 return 0; 195 } 196 197 #else 198 199 SKIP_MAIN_UNDEFINED("AF_SMC") 200 201 #endif 202