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