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 "test_nlattr.h" 33 #ifdef HAVE_LINUX_NEIGHBOUR_H 34 # include <linux/neighbour.h> 35 #endif 36 #include <linux/rtnetlink.h> 37 38 #define NDTA_PARMS 6 39 #define NDTPA_IFINDEX 1 40 41 static void 42 init_ndtmsg(struct nlmsghdr *const nlh, const unsigned int msg_len) 43 { 44 SET_STRUCT(struct nlmsghdr, nlh, 45 .nlmsg_len = msg_len, 46 .nlmsg_type = RTM_GETNEIGHTBL, 47 .nlmsg_flags = NLM_F_DUMP 48 ); 49 50 struct ndtmsg *const msg = NLMSG_DATA(nlh); 51 SET_STRUCT(struct ndtmsg, msg, 52 .ndtm_family = AF_NETLINK 53 ); 54 } 55 56 static void 57 print_ndtmsg(const unsigned int msg_len) 58 { 59 printf("{len=%u, type=RTM_GETNEIGHTBL, flags=NLM_F_DUMP" 60 ", seq=0, pid=0}, {ndtm_family=AF_NETLINK}", 61 msg_len); 62 } 63 64 int 65 main(void) 66 { 67 skip_if_unavailable("/proc/self/fd/"); 68 69 const int fd = create_nl_socket(NETLINK_ROUTE); 70 const unsigned int hdrlen = sizeof(struct ndtmsg); 71 void *nlh0 = midtail_alloc(NLMSG_SPACE(hdrlen), NLA_HDRLEN + 11 * 8); 72 73 static char pattern[4096]; 74 fill_memory_ex(pattern, sizeof(pattern), 'a', 'z' - 'a' + 1); 75 76 const unsigned int nla_type = 0xffff & NLA_TYPE_MASK; 77 char nla_type_str[256]; 78 sprintf(nla_type_str, "%#x /* NDTA_??? */", nla_type); 79 TEST_NLATTR_(fd, nlh0, hdrlen, 80 init_ndtmsg, print_ndtmsg, 81 nla_type, nla_type_str, 82 4, pattern, 4, 83 print_quoted_hex(pattern, 4)); 84 85 #ifdef HAVE_STRUCT_NDT_CONFIG 86 static const struct ndt_config ndtc = { 87 .ndtc_key_len = 0xabcd, 88 .ndtc_entry_size = 0xbcda, 89 .ndtc_entries = 0xcdabedad, 90 .ndtc_last_flush = 0xdebaedba, 91 .ndtc_last_rand = 0xedadedab, 92 .ndtc_hash_rnd = 0xfeadedaf, 93 .ndtc_hash_mask = 0xadbcdead, 94 .ndtc_hash_chain_gc = 0xbdaedacd, 95 .ndtc_proxy_qlen = 0xcdeaedab 96 }; 97 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 98 init_ndtmsg, print_ndtmsg, 99 NDTA_CONFIG, pattern, ndtc, 100 PRINT_FIELD_U("{", ndtc, ndtc_key_len); 101 PRINT_FIELD_U(", ", ndtc, ndtc_entry_size); 102 PRINT_FIELD_U(", ", ndtc, ndtc_entries); 103 PRINT_FIELD_U(", ", ndtc, ndtc_last_flush); 104 PRINT_FIELD_U(", ", ndtc, ndtc_last_rand); 105 PRINT_FIELD_U(", ", ndtc, ndtc_hash_rnd); 106 PRINT_FIELD_0X(", ", ndtc, ndtc_hash_mask); 107 PRINT_FIELD_U(", ", ndtc, ndtc_hash_chain_gc); 108 PRINT_FIELD_U(", ", ndtc, ndtc_proxy_qlen); 109 printf("}")); 110 #endif /* HAVE_STRUCT_NDT_CONFIG */ 111 112 static const struct nlattr nla = { 113 .nla_len = sizeof(nla), 114 .nla_type = NDTPA_IFINDEX 115 }; 116 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 117 init_ndtmsg, print_ndtmsg, 118 NDTA_PARMS, pattern, nla, 119 PRINT_FIELD_U("{", nla, nla_len); 120 printf(", nla_type=NDTPA_IFINDEX}")); 121 122 #ifdef HAVE_STRUCT_NDT_STATS 123 static const struct ndt_stats ndtst = { 124 .ndts_allocs = 0xabcdedabedadedfa, 125 .ndts_destroys = 0xbcdefabefacdbaad, 126 .ndts_hash_grows = 0xcdbadefacdcbaede, 127 .ndts_res_failed = 0xdedbaecfdbcadcfe, 128 .ndts_lookups = 0xedfafdedbdadedec, 129 .ndts_hits = 0xfebdeadebcddeade, 130 .ndts_rcv_probes_mcast = 0xadebfeadecddeafe, 131 .ndts_rcv_probes_ucast = 0xbcdefeacdadecdfe, 132 .ndts_periodic_gc_runs = 0xedffeadedeffbecc, 133 .ndts_forced_gc_runs = 0xfeefefeabedeedcd, 134 #ifdef HAVE_STRUCT_NDT_STATS_NDTS_TABLE_FULLS 135 .ndts_table_fulls = 0xadebfefaecdfeade 136 #endif /* HAVE_STRUCT_NDT_STATS_NDTS_TABLE_FULLS */ 137 }; 138 TEST_NLATTR_OBJECT(fd, nlh0, hdrlen, 139 init_ndtmsg, print_ndtmsg, 140 NDTA_STATS, pattern, ndtst, 141 PRINT_FIELD_U("{", ndtst, ndts_allocs); 142 PRINT_FIELD_U(", ", ndtst, ndts_destroys); 143 PRINT_FIELD_U(", ", ndtst, ndts_hash_grows); 144 PRINT_FIELD_U(", ", ndtst, ndts_res_failed); 145 PRINT_FIELD_U(", ", ndtst, ndts_lookups); 146 PRINT_FIELD_U(", ", ndtst, ndts_hits); 147 PRINT_FIELD_U(", ", ndtst, ndts_rcv_probes_mcast); 148 PRINT_FIELD_U(", ", ndtst, ndts_rcv_probes_ucast); 149 PRINT_FIELD_U(", ", ndtst, ndts_periodic_gc_runs); 150 PRINT_FIELD_U(", ", ndtst, ndts_forced_gc_runs); 151 #ifdef HAVE_STRUCT_NDT_STATS_NDTS_TABLE_FULLS 152 PRINT_FIELD_U(", ", ndtst, ndts_table_fulls); 153 #endif /* HAVE_STRUCT_NDT_STATS_NDTS_TABLE_FULLS */ 154 printf("}")); 155 #endif /* HAVE_STRUCT_NDT_STATS */ 156 157 puts("+++ exited with 0 +++"); 158 return 0; 159 } 160