Home | History | Annotate | Download | only in tests-mx32
      1 /*
      2  * Copyright (c) 2017 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 <string.h>
     33 #include <sys/socket.h>
     34 #include "netlink.h"
     35 #include <linux/rtnetlink.h>
     36 
     37 static void
     38 init_nlattr(struct nlattr *const nla,
     39 	    const uint16_t nla_len,
     40 	    const uint16_t nla_type,
     41 	    const void *const src,
     42 	    const size_t n)
     43 {
     44 	SET_STRUCT(struct nlattr, nla,
     45 		.nla_len = nla_len,
     46 		.nla_type = nla_type,
     47 	);
     48 
     49 	memcpy(RTA_DATA(nla), src, n);
     50 }
     51 
     52 static void
     53 print_nlattr(const unsigned int nla_len, const char *const nla_type)
     54 {
     55 	printf(", {{nla_len=%u, nla_type=%s}, ", nla_len, nla_type);
     56 }
     57 
     58 #define TEST_NLATTR_(fd_, nlh0_, hdrlen_,				\
     59 		     init_msg_, print_msg_,				\
     60 		     nla_type_, nla_type_str_,				\
     61 		     nla_data_len_, src_, slen_, ...)			\
     62 	do {								\
     63 		struct nlmsghdr *const nlh =				\
     64 			(nlh0_) - (NLA_HDRLEN + (slen_));		\
     65 		struct nlattr *const nla = NLMSG_ATTR(nlh, (hdrlen_));	\
     66 		const unsigned int nla_len =				\
     67 			NLA_HDRLEN + (nla_data_len_);			\
     68 		const unsigned int msg_len =				\
     69 			NLMSG_SPACE(hdrlen_) + nla_len;			\
     70 									\
     71 		(init_msg_)(nlh, msg_len);				\
     72 		init_nlattr(nla, nla_len, (nla_type_),			\
     73 			   (src_), (slen_));				\
     74 									\
     75 		const char *const errstr =				\
     76 			sprintrc(sendto((fd_), nlh, msg_len,		\
     77 					MSG_DONTWAIT, NULL, 0));	\
     78 									\
     79 		printf("sendto(%d, {", (fd_));				\
     80 		(print_msg_)(msg_len);					\
     81 		print_nlattr(nla_len, (nla_type_str_));			\
     82 									\
     83 		{ __VA_ARGS__; }					\
     84 									\
     85 		printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",		\
     86 		       msg_len, errstr);				\
     87 	} while (0)
     88 
     89 #define TEST_NLATTR(fd_, nlh0_, hdrlen_,				\
     90 		    init_msg_, print_msg_,				\
     91 		    nla_type_,						\
     92 		    nla_data_len_, src_, slen_, ...)			\
     93 	TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),				\
     94 		(init_msg_), (print_msg_),				\
     95 		(nla_type_), #nla_type_,				\
     96 		(nla_data_len_), (src_), (slen_), __VA_ARGS__)
     97 
     98 #define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_,				\
     99 			   init_msg_, print_msg_,			\
    100 			   nla_type_, pattern_, obj_, ...)		\
    101 	do {								\
    102 		const int plen = sizeof(obj_) - 1 > DEFAULT_STRLEN	\
    103 			? DEFAULT_STRLEN : (int) sizeof(obj_) - 1;	\
    104 		/* len < sizeof(obj_) */				\
    105 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    106 			(init_msg_), (print_msg_),			\
    107 			(nla_type_), #nla_type_,			\
    108 			sizeof(obj_) - 1,				\
    109 			(pattern_), sizeof(obj_) - 1,			\
    110 			printf("\"%.*s\"", plen, (pattern_)));		\
    111 		/* short read of sizeof(obj_) */			\
    112 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    113 			(init_msg_), (print_msg_),			\
    114 			(nla_type_), #nla_type_,			\
    115 			sizeof(obj_),					\
    116 			(pattern_), sizeof(obj_) - 1,			\
    117 			printf("%p",					\
    118 			       RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))));	\
    119 		/* sizeof(obj_) */					\
    120 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    121 			(init_msg_), (print_msg_),			\
    122 			(nla_type_), #nla_type_,			\
    123 			sizeof(obj_),					\
    124 			&(obj_), sizeof(obj_),				\
    125 			__VA_ARGS__);					\
    126 	} while (0)
    127 
    128 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_,				\
    129 			  init_msg_, print_msg_,			\
    130 			  nla_type_, pattern_, obj_, print_elem_)	\
    131 	do {								\
    132 		const int plen =					\
    133 			sizeof((obj_)[0]) - 1 > DEFAULT_STRLEN		\
    134 			? DEFAULT_STRLEN : (int) sizeof((obj_)[0]) - 1;	\
    135 		/* len < sizeof((obj_)[0]) */				\
    136 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    137 			(init_msg_), (print_msg_),			\
    138 			(nla_type_), #nla_type_,			\
    139 			sizeof((obj_)[0]) - 1,				\
    140 			(pattern_), sizeof((obj_)[0]) - 1,		\
    141 			printf("\"%.*s\"", plen, (pattern_)));		\
    142 		/* sizeof((obj_)[0]) < len < sizeof(obj_) */		\
    143 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    144 			(init_msg_), (print_msg_),			\
    145 			(nla_type_), #nla_type_,			\
    146 			sizeof(obj_) - 1,				\
    147 			&(obj_), sizeof(obj_) - 1,			\
    148 			printf("[");					\
    149 			size_t i;					\
    150 			for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {	\
    151 				if (i) printf(", ");			\
    152 				(print_elem_)(&(obj_)[i]);		\
    153 			}						\
    154 			printf("]"));					\
    155 		/* short read of sizeof(obj_) */			\
    156 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    157 			(init_msg_), (print_msg_),			\
    158 			(nla_type_), #nla_type_,			\
    159 			sizeof(obj_),					\
    160 			&(obj_), sizeof(obj_) - 1,			\
    161 			printf("[");					\
    162 			size_t i;					\
    163 			for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {	\
    164 				if (i) printf(", ");			\
    165 				(print_elem_)(&(obj_)[i]);		\
    166 			}						\
    167 			printf(", %p]",					\
    168 			       RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))	\
    169 			        + sizeof((obj_)[0])));			\
    170 		/* sizeof(obj_) */					\
    171 		TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),			\
    172 			(init_msg_), (print_msg_),			\
    173 			(nla_type_), #nla_type_,			\
    174 			sizeof(obj_),					\
    175 			&(obj_), sizeof(obj_),				\
    176 			printf("[");					\
    177 			size_t i;					\
    178 			for (i = 0; i < ARRAY_SIZE(obj_); ++i) {	\
    179 				if (i) printf(", ");			\
    180 				(print_elem_)(&(obj_)[i]);		\
    181 			}						\
    182 			printf("]"));					\
    183 	} while (0)
    184