]> granicus.if.org Git - strace/blob - tests/test_nlattr.h
tests: extend TEST_NETLINK_OBJECT macro
[strace] / tests / test_nlattr.h
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 TEST_NLATTR_nla =                  \
66                         NLMSG_ATTR(nlh, (hdrlen_));                     \
67                 const unsigned int nla_len =                            \
68                         NLA_HDRLEN + (nla_data_len_);                   \
69                 const unsigned int msg_len =                            \
70                         NLMSG_SPACE(hdrlen_) + nla_len;                 \
71                                                                         \
72                 (init_msg_)(nlh, msg_len);                              \
73                 init_nlattr(TEST_NLATTR_nla, nla_len, (nla_type_),      \
74                            (src_), (slen_));                            \
75                                                                         \
76                 const char *const errstr =                              \
77                         sprintrc(sendto((fd_), nlh, msg_len,            \
78                                         MSG_DONTWAIT, NULL, 0));        \
79                                                                         \
80                 printf("sendto(%d, {", (fd_));                          \
81                 (print_msg_)(msg_len);                                  \
82                 print_nlattr(nla_len, (nla_type_str_));                 \
83                                                                         \
84                 { __VA_ARGS__; }                                        \
85                                                                         \
86                 printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",         \
87                        msg_len, errstr);                                \
88         } while (0)
89
90 #define TEST_NLATTR(fd_, nlh0_, hdrlen_,                                \
91                     init_msg_, print_msg_,                              \
92                     nla_type_,                                          \
93                     nla_data_len_, src_, slen_, ...)                    \
94         TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                         \
95                 (init_msg_), (print_msg_),                              \
96                 (nla_type_), #nla_type_,                                \
97                 (nla_data_len_), (src_), (slen_), __VA_ARGS__)
98
99 #define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_,                         \
100                            init_msg_, print_msg_,                       \
101                            nla_type_, pattern_, obj_, ...)              \
102         do {                                                            \
103                 const unsigned int plen =                               \
104                         sizeof(obj_) - 1 > DEFAULT_STRLEN               \
105                         ? DEFAULT_STRLEN : (int) sizeof(obj_) - 1;      \
106                 /* len < sizeof(obj_) */                                \
107                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
108                         (init_msg_), (print_msg_),                      \
109                         (nla_type_), #nla_type_,                        \
110                         plen, (pattern_), plen,                         \
111                         print_quoted_hex((pattern_), plen));            \
112                 /* short read of sizeof(obj_) */                        \
113                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
114                         (init_msg_), (print_msg_),                      \
115                         (nla_type_), #nla_type_,                        \
116                         sizeof(obj_),                                   \
117                         (pattern_), sizeof(obj_) - 1,                   \
118                         printf("%p",                                    \
119                                RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))));  \
120                 /* sizeof(obj_) */                                      \
121                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
122                         (init_msg_), (print_msg_),                      \
123                         (nla_type_), #nla_type_,                        \
124                         sizeof(obj_),                                   \
125                         &(obj_), sizeof(obj_),                          \
126                         __VA_ARGS__);                                   \
127         } while (0)
128
129 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_,                          \
130                           init_msg_, print_msg_,                        \
131                           nla_type_, pattern_, obj_, print_elem_)       \
132         do {                                                            \
133                 const unsigned int plen =                               \
134                         sizeof((obj_)[0]) - 1 > DEFAULT_STRLEN          \
135                         ? DEFAULT_STRLEN : (int) sizeof((obj_)[0]) - 1; \
136                 /* len < sizeof((obj_)[0]) */                           \
137                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
138                         (init_msg_), (print_msg_),                      \
139                         (nla_type_), #nla_type_,                        \
140                         plen, (pattern_), plen,                         \
141                         print_quoted_hex((pattern_), plen));            \
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)