1 /* 2 * Copyright (c) 2017 JingPiao Chen <chenjingpiao (at) 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 31 #include <stdio.h> 32 #include <stddef.h> 33 #include "test_nlattr.h" 34 35 #include <linux/if.h> 36 #include <linux/if_arp.h> 37 #ifdef HAVE_LINUX_IF_LINK_H 38 # include <linux/if_link.h> 39 #endif 40 #include <linux/rtnetlink.h> 41 42 #ifndef IFLA_LINKINFO 43 # define IFLA_LINKINFO 18 44 #endif 45 #ifndef IFLA_VF_PORTS 46 # define IFLA_VF_PORTS 24 47 #endif 48 #define IFLA_LINK_NETNSID 37 49 50 #ifndef IFLA_INFO_KIND 51 # define IFLA_INFO_KIND 1 52 #endif 53 54 #ifndef IFLA_VF_PORT 55 # define IFLA_VF_PORT 1 56 #endif 57 58 static void 59 init_ifinfomsg(struct nlmsghdr *const nlh, const unsigned int msg_len) 60 { 61 SET_STRUCT(struct nlmsghdr, nlh, 62 .nlmsg_len = msg_len, 63 .nlmsg_type = RTM_GETLINK, 64 .nlmsg_flags = NLM_F_DUMP 65 ); 66 67 struct ifinfomsg *const msg = NLMSG_DATA(nlh); 68 SET_STRUCT(struct ifinfomsg, msg, 69 .ifi_family = AF_UNIX, 70 .ifi_type = ARPHRD_LOOPBACK, 71 .ifi_index = ifindex_lo(), 72 .ifi_flags = IFF_UP, 73 ); 74 } 75 76 static void 77 print_ifinfomsg(const unsigned int msg_len) 78 { 79 printf("{len=%u, type=RTM_GETLINK, flags=NLM_F_DUMP" 80 ", seq=0, pid=0}, {ifi_family=AF_UNIX" 81 ", ifi_type=ARPHRD_LOOPBACK" 82 ", ifi_index=" IFINDEX_LO_STR 83 ", ifi_flags=IFF_UP, ifi_change=0}", 84 msg_len); 85 } 86 87 int 88 main(void) 89 { 90 skip_if_unavailable("/proc/self/fd/"); 91 92 const int fd = create_nl_socket(NETLINK_ROUTE); 93 const unsigned int hdrlen = sizeof(struct ifinfomsg); 94 void *nlh0 = tail_alloc(NLMSG_SPACE(hdrlen)); 95 96 static char pattern[4096]; 97 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1); 98 99 const unsigned int nla_type = 0xffff & NLA_TYPE_MASK; 100 char nla_type_str[256]; 101 sprintf(nla_type_str, "%#x /* IFLA_??? */", nla_type); 102 TEST_NLATTR_(fd, nlh0, hdrlen, 103 init_ifinfomsg, print_ifinfomsg, 104 nla_type, nla_type_str, 105 4, pattern, 4, 106 print_quoted_hex(pattern, 4)); 107 108 const int32_t netnsid = 0xacbdabda; 109 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 110 init_ifinfomsg, print_ifinfomsg, 111 IFLA_LINK_NETNSID, pattern, netnsid, 112 printf("%d", netnsid)); 113 114 static const struct rtnl_link_stats st = { 115 .rx_packets = 0xabcdefac, 116 .tx_packets = 0xbcdacdab, 117 .rx_bytes = 0xcdbafaab, 118 .tx_bytes = 0xdafabadb, 119 .rx_errors = 0xeabcdaeb, 120 .tx_errors = 0xfefabeab, 121 .rx_dropped = 0xadbafafb, 122 .tx_dropped = 0xbdffabda, 123 .multicast = 0xcdabdfea, 124 .collisions = 0xefadbaeb, 125 .rx_length_errors = 0xfabffabd, 126 .rx_over_errors = 0xafbafabc, 127 .rx_crc_errors = 0xbfdabdad, 128 .rx_frame_errors = 0xcfdabfad, 129 .rx_fifo_errors = 0xddfdebad, 130 .rx_missed_errors = 0xefabdcba, 131 .tx_aborted_errors = 0xefdadbfa, 132 .tx_carrier_errors = 0xfaefbada, 133 .tx_fifo_errors = 0xaebdffab, 134 .tx_heartbeat_errors = 0xbadebaaf, 135 .tx_window_errors = 0xcdafbada, 136 .rx_compressed = 0xdeffadbd, 137 .tx_compressed = 0xefdadfab 138 }; 139 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 140 init_ifinfomsg, print_ifinfomsg, 141 IFLA_STATS, pattern, st, 142 PRINT_FIELD_U("{", st, rx_packets); 143 PRINT_FIELD_U(", ", st, tx_packets); 144 PRINT_FIELD_U(", ", st, rx_bytes); 145 PRINT_FIELD_U(", ", st, tx_bytes); 146 PRINT_FIELD_U(", ", st, rx_errors); 147 PRINT_FIELD_U(", ", st, tx_errors); 148 PRINT_FIELD_U(", ", st, rx_dropped); 149 PRINT_FIELD_U(", ", st, tx_dropped); 150 PRINT_FIELD_U(", ", st, multicast); 151 PRINT_FIELD_U(", ", st, collisions); 152 PRINT_FIELD_U(", ", st, rx_length_errors); 153 PRINT_FIELD_U(", ", st, rx_over_errors); 154 PRINT_FIELD_U(", ", st, rx_crc_errors); 155 PRINT_FIELD_U(", ", st, rx_frame_errors); 156 PRINT_FIELD_U(", ", st, rx_fifo_errors); 157 PRINT_FIELD_U(", ", st, rx_missed_errors); 158 PRINT_FIELD_U(", ", st, tx_aborted_errors); 159 PRINT_FIELD_U(", ", st, tx_carrier_errors); 160 PRINT_FIELD_U(", ", st, tx_fifo_errors); 161 PRINT_FIELD_U(", ", st, tx_heartbeat_errors); 162 PRINT_FIELD_U(", ", st, tx_window_errors); 163 PRINT_FIELD_U(", ", st, rx_compressed); 164 PRINT_FIELD_U(", ", st, tx_compressed); 165 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER 166 PRINT_FIELD_U(", ", st, rx_nohandler); 167 #endif 168 printf("}")); 169 170 #ifdef HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER 171 const unsigned int sizeof_stats = 172 offsetofend(struct rtnl_link_stats, tx_compressed); 173 TEST_NLATTR(fd, nlh0, hdrlen, 174 init_ifinfomsg, print_ifinfomsg, 175 IFLA_STATS, sizeof_stats, &st, sizeof_stats, 176 PRINT_FIELD_U("{", st, rx_packets); 177 PRINT_FIELD_U(", ", st, tx_packets); 178 PRINT_FIELD_U(", ", st, rx_bytes); 179 PRINT_FIELD_U(", ", st, tx_bytes); 180 PRINT_FIELD_U(", ", st, rx_errors); 181 PRINT_FIELD_U(", ", st, tx_errors); 182 PRINT_FIELD_U(", ", st, rx_dropped); 183 PRINT_FIELD_U(", ", st, tx_dropped); 184 PRINT_FIELD_U(", ", st, multicast); 185 PRINT_FIELD_U(", ", st, collisions); 186 PRINT_FIELD_U(", ", st, rx_length_errors); 187 PRINT_FIELD_U(", ", st, rx_over_errors); 188 PRINT_FIELD_U(", ", st, rx_crc_errors); 189 PRINT_FIELD_U(", ", st, rx_frame_errors); 190 PRINT_FIELD_U(", ", st, rx_fifo_errors); 191 PRINT_FIELD_U(", ", st, rx_missed_errors); 192 PRINT_FIELD_U(", ", st, tx_aborted_errors); 193 PRINT_FIELD_U(", ", st, tx_carrier_errors); 194 PRINT_FIELD_U(", ", st, tx_fifo_errors); 195 PRINT_FIELD_U(", ", st, tx_heartbeat_errors); 196 PRINT_FIELD_U(", ", st, tx_window_errors); 197 PRINT_FIELD_U(", ", st, rx_compressed); 198 PRINT_FIELD_U(", ", st, tx_compressed); 199 printf("}")); 200 #endif /* HAVE_STRUCT_RTNL_LINK_STATS_RX_NOHANDLER */ 201 202 static const struct rtnl_link_ifmap map = { 203 .mem_start = 0xadcbefedefbcdedb, 204 .mem_end = 0xefcbeabdecdcdefa, 205 .base_addr = 0xaddbeabdfaacdbae, 206 .irq = 0xefaf, 207 .dma = 0xab, 208 .port = 0xcd 209 }; 210 const unsigned int sizeof_ifmap = 211 offsetofend(struct rtnl_link_ifmap, port); 212 const unsigned int plen = sizeof_ifmap - 1 > DEFAULT_STRLEN 213 ? DEFAULT_STRLEN 214 : (int) sizeof_ifmap - 1; 215 /* len < sizeof_ifmap */ 216 TEST_NLATTR(fd, nlh0, hdrlen, 217 init_ifinfomsg, print_ifinfomsg, 218 IFLA_MAP, plen, pattern, plen, 219 print_quoted_hex(pattern, plen)); 220 221 /* short read of sizeof_ifmap */ 222 TEST_NLATTR(fd, nlh0, hdrlen, 223 init_ifinfomsg, print_ifinfomsg, 224 IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap - 1, 225 printf("%p", RTA_DATA(TEST_NLATTR_nla))); 226 227 /* sizeof_ifmap */ 228 TEST_NLATTR(fd, nlh0, hdrlen, 229 init_ifinfomsg, print_ifinfomsg, 230 IFLA_MAP, sizeof_ifmap, &map, sizeof_ifmap, 231 PRINT_FIELD_X("{", map, mem_start); 232 PRINT_FIELD_X(", ", map, mem_end); 233 PRINT_FIELD_X(", ", map, base_addr); 234 PRINT_FIELD_U(", ", map, irq); 235 PRINT_FIELD_U(", ", map, dma); 236 PRINT_FIELD_U(", ", map, port); 237 printf("}")); 238 239 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64 240 static const struct rtnl_link_stats64 st64 = { 241 .rx_packets = 0xadcbefedefbcdedb, 242 .tx_packets = 0xbdabdedabdcdeabd, 243 .rx_bytes = 0xcdbaefbaeadfabec, 244 .tx_bytes = 0xdbaedbafabbeacdb, 245 .rx_errors = 0xefabfdaefabaefab, 246 .tx_errors = 0xfaebfabfabbaeabf, 247 .rx_dropped = 0xacdbaedbadbabeba, 248 .tx_dropped = 0xbcdeffebdabeadbe, 249 .multicast = 0xeeffbaeabaeffabe, 250 .collisions = 0xffbaefcefbafacef, 251 .rx_length_errors = 0xaabbdeabceffdecb, 252 .rx_over_errors = 0xbbdcdadebadeaeed, 253 .rx_crc_errors= 0xccdeabecefaedbef, 254 .rx_frame_errors = 0xddbedaedebcedaef, 255 .rx_fifo_errors = 0xeffbadefafdaeaab, 256 .rx_missed_errors = 0xfefaebccceadeecd, 257 .tx_aborted_errors = 0xabcdadefcdadef, 258 .tx_carrier_errors = 0xbccdafaeeaaefe, 259 .tx_fifo_errors = 0xcddefdbedeadce, 260 .tx_heartbeat_errors = 0xedaededdadcdea, 261 .tx_window_errors = 0xfdacdeaccedcda, 262 .rx_compressed = 0xacdbbcacdbccef, 263 .tx_compressed = 0xbcdadefcdedfea 264 }; 265 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 266 init_ifinfomsg, print_ifinfomsg, 267 IFLA_STATS64, pattern, st64, 268 PRINT_FIELD_U("{", st64, rx_packets); 269 PRINT_FIELD_U(", ", st64, tx_packets); 270 PRINT_FIELD_U(", ", st64, rx_bytes); 271 PRINT_FIELD_U(", ", st64, tx_bytes); 272 PRINT_FIELD_U(", ", st64, rx_errors); 273 PRINT_FIELD_U(", ", st64, tx_errors); 274 PRINT_FIELD_U(", ", st64, rx_dropped); 275 PRINT_FIELD_U(", ", st64, tx_dropped); 276 PRINT_FIELD_U(", ", st64, multicast); 277 PRINT_FIELD_U(", ", st64, collisions); 278 PRINT_FIELD_U(", ", st64, rx_length_errors); 279 PRINT_FIELD_U(", ", st64, rx_over_errors); 280 PRINT_FIELD_U(", ", st64, rx_crc_errors); 281 PRINT_FIELD_U(", ", st64, rx_frame_errors); 282 PRINT_FIELD_U(", ", st64, rx_fifo_errors); 283 PRINT_FIELD_U(", ", st64, rx_missed_errors); 284 PRINT_FIELD_U(", ", st64, tx_aborted_errors); 285 PRINT_FIELD_U(", ", st64, tx_carrier_errors); 286 PRINT_FIELD_U(", ", st64, tx_fifo_errors); 287 PRINT_FIELD_U(", ", st64, tx_heartbeat_errors); 288 PRINT_FIELD_U(", ", st64, tx_window_errors); 289 PRINT_FIELD_U(", ", st64, rx_compressed); 290 PRINT_FIELD_U(", ", st64, tx_compressed); 291 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER 292 PRINT_FIELD_U(", ", st64, rx_nohandler); 293 #endif 294 printf("}")); 295 296 #ifdef HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER 297 const unsigned int sizeof_stats64 = 298 offsetofend(struct rtnl_link_stats64, tx_compressed); 299 TEST_NLATTR(fd, nlh0, hdrlen, 300 init_ifinfomsg, print_ifinfomsg, 301 IFLA_STATS64, sizeof_stats64, &st64, sizeof_stats64, 302 PRINT_FIELD_U("{", st64, rx_packets); 303 PRINT_FIELD_U(", ", st64, tx_packets); 304 PRINT_FIELD_U(", ", st64, rx_bytes); 305 PRINT_FIELD_U(", ", st64, tx_bytes); 306 PRINT_FIELD_U(", ", st64, rx_errors); 307 PRINT_FIELD_U(", ", st64, tx_errors); 308 PRINT_FIELD_U(", ", st64, rx_dropped); 309 PRINT_FIELD_U(", ", st64, tx_dropped); 310 PRINT_FIELD_U(", ", st64, multicast); 311 PRINT_FIELD_U(", ", st64, collisions); 312 PRINT_FIELD_U(", ", st64, rx_length_errors); 313 PRINT_FIELD_U(", ", st64, rx_over_errors); 314 PRINT_FIELD_U(", ", st64, rx_crc_errors); 315 PRINT_FIELD_U(", ", st64, rx_frame_errors); 316 PRINT_FIELD_U(", ", st64, rx_fifo_errors); 317 PRINT_FIELD_U(", ", st64, rx_missed_errors); 318 PRINT_FIELD_U(", ", st64, tx_aborted_errors); 319 PRINT_FIELD_U(", ", st64, tx_carrier_errors); 320 PRINT_FIELD_U(", ", st64, tx_fifo_errors); 321 PRINT_FIELD_U(", ", st64, tx_heartbeat_errors); 322 PRINT_FIELD_U(", ", st64, tx_window_errors); 323 PRINT_FIELD_U(", ", st64, rx_compressed); 324 PRINT_FIELD_U(", ", st64, tx_compressed); 325 printf("}")); 326 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64_RX_NOHANDLER */ 327 #endif /* HAVE_STRUCT_RTNL_LINK_STATS64 */ 328 329 struct nlattr nla = { 330 .nla_len = sizeof(nla), 331 .nla_type = IFLA_INFO_KIND, 332 }; 333 TEST_NLATTR(fd, nlh0, hdrlen, 334 init_ifinfomsg, print_ifinfomsg, 335 IFLA_LINKINFO, sizeof(nla), &nla, sizeof(nla), 336 printf("{nla_len=%u, nla_type=IFLA_INFO_KIND}", 337 nla.nla_len)); 338 339 nla.nla_type = IFLA_VF_PORT; 340 TEST_NLATTR(fd, nlh0, hdrlen, 341 init_ifinfomsg, print_ifinfomsg, 342 IFLA_VF_PORTS, sizeof(nla), &nla, sizeof(nla), 343 printf("{nla_len=%u, nla_type=IFLA_VF_PORT}", 344 nla.nla_len)); 345 346 puts("+++ exited with 0 +++"); 347 return 0; 348 } 349