Home | History | Annotate | Download | only in tests-m32
      1 /*
      2  * Copyright (c) 2017-2018 The strace developers.
      3  * All rights reserved.
      4  *
      5  * Redistribution and use in source and binary forms, with or without
      6  * modification, are permitted provided that the following conditions
      7  * are met:
      8  * 1. Redistributions of source code must retain the above copyright
      9  *    notice, this list of conditions and the following disclaimer.
     10  * 2. Redistributions in binary form must reproduce the above copyright
     11  *    notice, this list of conditions and the following disclaimer in the
     12  *    documentation and/or other materials provided with the distribution.
     13  * 3. The name of the author may not be used to endorse or promote products
     14  *    derived from this software without specific prior written permission.
     15  *
     16  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
     17  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
     18  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
     19  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
     20  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
     21  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
     22  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
     23  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     24  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
     25  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     26  */
     27 
     28 #include "tests.h"
     29 #include "print_fields.h"
     30 
     31 #include <stdio.h>
     32 #include <stdint.h>
     33 #include <string.h>
     34 #include <sys/socket.h>
     35 #include "netlink.h"
     36 #include <linux/rtnetlink.h>
     37 
     38 static void
     39 init_nlattr(struct nlattr *const nla,
     40 	    const uint16_t nla_len,
     41 	    const uint16_t nla_type,
     42 	    const void *const src,
     43 	    const size_t n)
     44 {
     45 	SET_STRUCT(struct nlattr, nla,
     46 		.nla_len = nla_len,
     47 		.nla_type = nla_type,
     48 	);
     49 
     50 	memcpy(RTA_DATA(nla), src, n);
     51 }
     52 
     53 static void
     54 print_nlattr(const unsigned int nla_len, const char *const nla_type, bool add_data)
     55 {
     56 	printf(", %s{{nla_len=%u, nla_type=%s}, ",
     57 	       add_data ? "[" : "", nla_len, nla_type);
     58 }
     59 
     60 #define TEST_NLATTR_EX_(fd_, nlh0_, hdrlen_,				\
     61 		     init_msg_, print_msg_,				\
     62 		     nla_type_, nla_type_str_,				\
     63 		     nla_data_len_, nla_total_len_,			\
     64 		     src_, slen_, ...)					\
     65 	do {								\
     66 		struct nlmsghdr *const nlh =				\
     67 			(nlh0_) - (NLA_HDRLEN + (slen_));		\
     68 		struct nlattr *const TEST_NLATTR_nla =			\
     69 			NLMSG_ATTR(nlh, (hdrlen_));			\
     70 		const unsigned int nla_len =				\
     71 			NLA_HDRLEN + (nla_data_len_);			\
     72 		const unsigned int msg_len =				\
     73 			NLMSG_SPACE(hdrlen_) + NLA_HDRLEN + (nla_total_len_); \
     74 									\
     75 		(init_msg_)(nlh, msg_len);				\
     76 		init_nlattr(TEST_NLATTR_nla, nla_len, (nla_type_),	\
     77 			   (src_), (slen_));				\
     78 									\
     79 		const char *const errstr =				\
     80 			sprintrc(sendto((fd_), nlh, msg_len,		\
     81 					MSG_DONTWAIT, NULL, 0));	\
     82 									\
     83 		printf("sendto(%d, {", (fd_));				\
     84 		(print_msg_)(msg_len);					\
     85 		print_nlattr(nla_len, (nla_type_str_),			\
     86 			     (nla_total_len_) > (nla_data_len_));	\
     87 									\
     88 		{ __VA_ARGS__; }					\
     89 									\
     90 		if ((nla_total_len_) > (nla_data_len_))			\
     91 			printf("]");					\
     92 									\
     93 		printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",		\
     94 		       msg_len, errstr);				\
     95 	} while (0)
     96 
     97 #define TEST_NLATTR_(fd_, nlh0_, hdrlen_,				\
     98 		     init_msg_, print_msg_,				\
     99 		     nla_type_, nla_type_str_,				\
    100 		     nla_data_len_, src_, slen_, ...)			\
    101 	TEST_NLATTR_EX_((fd_), (nlh0_), (hdrlen_),			\
    102 			(init_msg_), (print_msg_),			\
    103 			(nla_type_), (nla_type_str_),			\
    104 			(nla_data_len_), (nla_data_len_),		\
    105 			(src_), (slen_), __VA_ARGS__)
    106 
    107 #define TEST_NLATTR(fd_, nlh0_, hdrlen_,				\
    108 		    init_msg_, print_msg_,				\
    109 		    nla_type_,						\
    110 		    nla_data_len_, src_, slen_, ...)			\
    111 	TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),				\
    112 		(init_msg_), (print_msg_),				\
    113 		(nla_type_), #nla_type_,				\
    114 		(nla_data_len_), (src_), (slen_), __VA_ARGS__)
    115 
    116 #define TEST_NLATTR_OBJECT_EX_(fd_, nlh0_, hdrlen_,			\
    117 			       init_msg_, print_msg_,			\
    118 			       nla_type_, nla_type_str_,		\
    119 			       pattern_, obj_, fallback_func, ...)	\
    120 	do {								\
    121 		const unsigned int plen =				\
    122 			sizeof(obj_) - 1 > DEFAULT_STRLEN		\
    123 			? DEFAULT_STRLEN : (int) sizeof(obj_) - 1;	\
    124 		/* len < sizeof(obj_) */				\
    125 		if (plen > 0)						\
    126 			TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),		\
    127 				(init_msg_), (print_msg_),		\
    128 				(nla_type_), (nla_type_str_),		\
    129 				plen, (pattern_), plen,			\
    130 				(fallback_func)((pattern_), plen));	\
    131 		/* short read of sizeof(obj_) */			\
    132 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    133 			(init_msg_), (print_msg_),			\
    134 			(nla_type_), (nla_type_str_),			\
    135 			sizeof(obj_),					\
    136 			(pattern_), sizeof(obj_) - 1,			\
    137 			printf("%p",					\
    138 			       RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))));	\
    139 		/* sizeof(obj_) */					\
    140 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    141 			(init_msg_), (print_msg_),			\
    142 			(nla_type_), (nla_type_str_),			\
    143 			sizeof(obj_),					\
    144 			&(obj_), sizeof(obj_),				\
    145 			__VA_ARGS__);					\
    146 	} while (0)
    147 
    148 #define TEST_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_,			\
    149 			      init_msg_, print_msg_,			\
    150 			      nla_type_,				\
    151 			      pattern_, obj_, fallback_func, ...)	\
    152 	TEST_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),		\
    153 			       (init_msg_), (print_msg_),		\
    154 			       (nla_type_), #nla_type_,			\
    155 			       (pattern_), (obj_), (fallback_func),	\
    156 			       __VA_ARGS__)
    157 
    158 #define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_,				\
    159 			   init_msg_, print_msg_,			\
    160 			   nla_type_, pattern_, obj_, ...)		\
    161 	TEST_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),		\
    162 			       (init_msg_), (print_msg_),		\
    163 			       (nla_type_), #nla_type_,			\
    164 			       (pattern_), (obj_), print_quoted_hex,	\
    165 			       __VA_ARGS__)
    166 
    167 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_,				\
    168 			  init_msg_, print_msg_,			\
    169 			  nla_type_, pattern_, obj_, print_elem_)	\
    170 	do {								\
    171 		const unsigned int plen =				\
    172 			sizeof((obj_)[0]) - 1 > DEFAULT_STRLEN		\
    173 			? DEFAULT_STRLEN : (int) sizeof((obj_)[0]) - 1;	\
    174 		/* len < sizeof((obj_)[0]) */				\
    175 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    176 			(init_msg_), (print_msg_),			\
    177 			(nla_type_), #nla_type_,			\
    178 			plen, (pattern_), plen,				\
    179 			print_quoted_hex((pattern_), plen));		\
    180 		/* sizeof((obj_)[0]) < len < sizeof(obj_) */		\
    181 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    182 			(init_msg_), (print_msg_),			\
    183 			(nla_type_), #nla_type_,			\
    184 			sizeof(obj_) - 1,				\
    185 			&(obj_), sizeof(obj_) - 1,			\
    186 			printf("[");					\
    187 			size_t i;					\
    188 			for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {	\
    189 				if (i) printf(", ");			\
    190 				(print_elem_)(&(obj_)[i], i);		\
    191 			}						\
    192 			printf("]"));					\
    193 		/* short read of sizeof(obj_) */			\
    194 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    195 			(init_msg_), (print_msg_),			\
    196 			(nla_type_), #nla_type_,			\
    197 			sizeof(obj_),					\
    198 			&(obj_), sizeof(obj_) - 1,			\
    199 			printf("[");					\
    200 			size_t i;					\
    201 			for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {	\
    202 				if (i) printf(", ");			\
    203 				(print_elem_)(&(obj_)[i], i);		\
    204 			}						\
    205 			printf(", ... /* %p */]",			\
    206 			       RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))	\
    207 			        + sizeof(obj_) - sizeof((obj_)[0])));	\
    208 		/* sizeof(obj_) */					\
    209 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    210 			(init_msg_), (print_msg_),			\
    211 			(nla_type_), #nla_type_,			\
    212 			sizeof(obj_),					\
    213 			&(obj_), sizeof(obj_),				\
    214 			printf("[");					\
    215 			size_t i;					\
    216 			for (i = 0; i < ARRAY_SIZE(obj_); ++i) {	\
    217 				if (i) printf(", ");			\
    218 				(print_elem_)(&(obj_)[i], i);		\
    219 			}						\
    220 			printf("]"));					\
    221 	} while (0)
    222 
    223 #define TEST_NESTED_NLATTR_OBJECT_EX_(fd_, nlh0_, hdrlen_,		\
    224 				      init_msg_, print_msg_,		\
    225 				      nla_type_, nla_type_str_,		\
    226 				      pattern_, obj_, fallback_func,	\
    227 				      depth_, ...)	\
    228 	do {								\
    229 		const unsigned int plen =				\
    230 			sizeof(obj_) - 1 > DEFAULT_STRLEN		\
    231 			? DEFAULT_STRLEN : (int) sizeof(obj_) - 1;	\
    232 		/* len < sizeof(obj_) */				\
    233 		if (plen > 0)						\
    234 			TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_, \
    235 				(hdrlen_) + NLA_HDRLEN * depth_,	\
    236 				(init_msg_), (print_msg_),		\
    237 				(nla_type_), (nla_type_str_),		\
    238 				plen, (pattern_), plen,			\
    239 				(fallback_func)((pattern_), plen);	\
    240 				size_t i;				\
    241 				for (i = 0; i < depth_; ++i)		\
    242 					printf("}"));			\
    243 		/* short read of sizeof(obj_) */			\
    244 		TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,	\
    245 			(hdrlen_) + NLA_HDRLEN * depth_,		\
    246 			(init_msg_), (print_msg_),			\
    247 			(nla_type_), (nla_type_str_),			\
    248 			sizeof(obj_),					\
    249 			(pattern_), sizeof(obj_) - 1,			\
    250 			printf("%p", RTA_DATA(TEST_NLATTR_nla));	\
    251 			size_t i;					\
    252 			for (i = 0; i < depth_; ++i)			\
    253 				printf("}"));				\
    254 		/* sizeof(obj_) */					\
    255 		TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,	\
    256 			(hdrlen_) + NLA_HDRLEN * depth_,		\
    257 			(init_msg_), (print_msg_),			\
    258 			(nla_type_), (nla_type_str_),			\
    259 			sizeof(obj_),					\
    260 			&(obj_), sizeof(obj_),				\
    261 			__VA_ARGS__;					\
    262 			size_t i;					\
    263 			for (i = 0; i < depth_; ++i)			\
    264 				printf("}"));				\
    265 	} while (0)
    266 
    267 #define TEST_NESTED_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_,		\
    268 				     init_msg_, print_msg_,		\
    269 				     nla_type_, pattern_, obj_,		\
    270 				     depth_, ...)			\
    271 	TEST_NESTED_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),	\
    272 				      (init_msg_), (print_msg_),	\
    273 				      (nla_type_), #nla_type_,		\
    274 				      (pattern_), (obj_),		\
    275 				      print_quoted_hex, (depth_),	\
    276 				      __VA_ARGS__)
    277 
    278 #define TEST_NESTED_NLATTR_OBJECT(fd_, nlh0_, hdrlen_,			\
    279 				  init_msg_, print_msg_,		\
    280 				  nla_type_, pattern_, obj_, ...)	\
    281 	TEST_NESTED_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),	\
    282 				      (init_msg_), (print_msg_),	\
    283 				      (nla_type_), #nla_type_,		\
    284 				      (pattern_), (obj_),		\
    285 				      print_quoted_hex, 1,		\
    286 				      __VA_ARGS__)
    287 
    288 #define TEST_NESTED_NLATTR_ARRAY_EX(fd_, nlh0_, hdrlen_,		\
    289 				 init_msg_, print_msg_,			\
    290 				 nla_type_, pattern_, obj_, depth_,	\
    291 				 print_elem_)				\
    292 	do {								\
    293 		const unsigned int plen =				\
    294 			sizeof((obj_)[0]) - 1 > DEFAULT_STRLEN		\
    295 			? DEFAULT_STRLEN : (int) sizeof((obj_)[0]) - 1;	\
    296 		/* len < sizeof((obj_)[0]) */				\
    297 		TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,	\
    298 			(hdrlen_) + NLA_HDRLEN * depth_,		\
    299 			(init_msg_), (print_msg_),			\
    300 			(nla_type_), #nla_type_,			\
    301 			plen, (pattern_), plen,				\
    302 			print_quoted_hex((pattern_), plen);		\
    303 			for (size_t i = 0; i < depth_; ++i)		\
    304 				printf("}"));				\
    305 		/* sizeof((obj_)[0]) < len < sizeof(obj_) */		\
    306 		TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,	\
    307 			(hdrlen_) + NLA_HDRLEN * depth_,		\
    308 			(init_msg_), (print_msg_),			\
    309 			(nla_type_), #nla_type_,			\
    310 			sizeof(obj_) - 1,				\
    311 			&(obj_), sizeof(obj_) - 1,			\
    312 			printf("[");					\
    313 			size_t i;					\
    314 			for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {	\
    315 				if (i) printf(", ");			\
    316 				(print_elem_)(&(obj_)[i], i);		\
    317 			}						\
    318 			printf("]");					\
    319 			for (i = 0; i < depth_; ++i)			\
    320 				printf("}"));				\
    321 		/* short read of sizeof(obj_) */			\
    322 		TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,	\
    323 			(hdrlen_) + NLA_HDRLEN * depth_,		\
    324 			(init_msg_), (print_msg_),			\
    325 			(nla_type_), #nla_type_,			\
    326 			sizeof(obj_),					\
    327 			&(obj_), sizeof(obj_) - 1,			\
    328 			printf("[");					\
    329 			size_t i;					\
    330 			for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {	\
    331 				if (i) printf(", ");			\
    332 				(print_elem_)(&(obj_)[i], i);		\
    333 			}						\
    334 			printf(", ... /* %p */]",			\
    335 			       RTA_DATA(TEST_NLATTR_nla)		\
    336 			        + sizeof(obj_) - sizeof((obj_)[0]));	\
    337 			for (i = 0; i < depth_; ++i)			\
    338 				printf("}"));				\
    339 		/* sizeof(obj_) */					\
    340 		TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,	\
    341 			(hdrlen_) + NLA_HDRLEN * depth_,		\
    342 			(init_msg_), (print_msg_),			\
    343 			(nla_type_), #nla_type_,			\
    344 			sizeof(obj_),					\
    345 			&(obj_), sizeof(obj_),				\
    346 			printf("[");					\
    347 			size_t i;					\
    348 			for (i = 0; i < ARRAY_SIZE(obj_); ++i) {	\
    349 				if (i) printf(", ");			\
    350 				(print_elem_)(&(obj_)[i], i);		\
    351 			}						\
    352 			printf("]");					\
    353 			for (i = 0; i < depth_; ++i)			\
    354 				printf("}"));				\
    355 	} while (0)
    356 
    357 #define TEST_NESTED_NLATTR_ARRAY(fd_, nlh0_, hdrlen_,			\
    358 				 init_msg_, print_msg_,			\
    359 				 nla_type_, pattern_, obj_, print_elem_)\
    360 	TEST_NESTED_NLATTR_ARRAY_EX((fd_), (nlh0_), (hdrlen_),		\
    361 				    (init_msg_), (print_msg_),		\
    362 				    nla_type_, (pattern_), (obj_), 1,	\
    363 				    (print_elem_))
    364