]> granicus.if.org Git - strace/blob - tests/test_nlattr.h
tests: introduce TEST_NLATTR_OBJECT_MINSZ
[strace] / tests / test_nlattr.h
1 /*
2  * Copyright (c) 2017-2018 The strace developers.
3  * All rights reserved.
4  *
5  * SPDX-License-Identifier: GPL-2.0-or-later
6  */
7
8 #include "tests.h"
9 #include "print_fields.h"
10
11 #include <stdio.h>
12 #include <stdint.h>
13 #include <string.h>
14 #include <sys/socket.h>
15 #include "netlink.h"
16 #include <linux/rtnetlink.h>
17
18 static void
19 init_nlattr(struct nlattr *const nla,
20             const uint16_t nla_len,
21             const uint16_t nla_type,
22             const void *const src,
23             const size_t n)
24 {
25         SET_STRUCT(struct nlattr, nla,
26                 .nla_len = nla_len,
27                 .nla_type = nla_type,
28         );
29
30         memcpy(RTA_DATA(nla), src, n);
31 }
32
33 static void
34 print_nlattr(const unsigned int nla_len, const char *const nla_type, bool add_data)
35 {
36         printf(", %s{{nla_len=%u, nla_type=%s}, ",
37                add_data ? "[" : "", nla_len, nla_type);
38 }
39
40 #define TEST_NLATTR_EX_(fd_, nlh0_, hdrlen_,                            \
41                      init_msg_, print_msg_,                             \
42                      nla_type_, nla_type_str_,                          \
43                      nla_data_len_, nla_total_len_,                     \
44                      src_, slen_, ...)                                  \
45         do {                                                            \
46                 struct nlmsghdr *const nlh =                            \
47                         (nlh0_) - (NLA_HDRLEN + (slen_));               \
48                 struct nlattr *const TEST_NLATTR_nla =                  \
49                         NLMSG_ATTR(nlh, (hdrlen_));                     \
50                 const unsigned int nla_len =                            \
51                         NLA_HDRLEN + (nla_data_len_);                   \
52                 const unsigned int msg_len =                            \
53                         NLMSG_SPACE(hdrlen_) + NLA_HDRLEN + (nla_total_len_); \
54                                                                         \
55                 (init_msg_)(nlh, msg_len);                              \
56                 init_nlattr(TEST_NLATTR_nla, nla_len, (nla_type_),      \
57                            (src_), (slen_));                            \
58                                                                         \
59                 const char *const errstr =                              \
60                         sprintrc(sendto((fd_), nlh, msg_len,            \
61                                         MSG_DONTWAIT, NULL, 0));        \
62                                                                         \
63                 printf("sendto(%d, {", (fd_));                          \
64                 (print_msg_)(msg_len);                                  \
65                 print_nlattr(nla_len, (nla_type_str_),                  \
66                              (nla_total_len_) > (nla_data_len_));       \
67                                                                         \
68                 { __VA_ARGS__; }                                        \
69                                                                         \
70                 if ((nla_total_len_) > (nla_data_len_))                 \
71                         printf("]");                                    \
72                                                                         \
73                 printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",         \
74                        msg_len, errstr);                                \
75         } while (0)
76
77 #define TEST_NLATTR_(fd_, nlh0_, hdrlen_,                               \
78                      init_msg_, print_msg_,                             \
79                      nla_type_, nla_type_str_,                          \
80                      nla_data_len_, src_, slen_, ...)                   \
81         TEST_NLATTR_EX_((fd_), (nlh0_), (hdrlen_),                      \
82                         (init_msg_), (print_msg_),                      \
83                         (nla_type_), (nla_type_str_),                   \
84                         (nla_data_len_), (nla_data_len_),               \
85                         (src_), (slen_), __VA_ARGS__)
86
87 #define TEST_NLATTR(fd_, nlh0_, hdrlen_,                                \
88                     init_msg_, print_msg_,                              \
89                     nla_type_,                                          \
90                     nla_data_len_, src_, slen_, ...)                    \
91         TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                         \
92                 (init_msg_), (print_msg_),                              \
93                 (nla_type_), #nla_type_,                                \
94                 (nla_data_len_), (src_), (slen_), __VA_ARGS__)
95
96 #define TEST_NLATTR_OBJECT_EX_(fd_, nlh0_, hdrlen_,                     \
97                                init_msg_, print_msg_,                   \
98                                nla_type_, nla_type_str_,                \
99                                pattern_, obj_, minsz_, fallback_func, ...) \
100         do {                                                            \
101                 const unsigned int plen = MIN((minsz_) - 1, DEFAULT_STRLEN); \
102                 /* len < sizeof(obj_) */                                \
103                 if (plen > 0)                                           \
104                         TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),         \
105                                 (init_msg_), (print_msg_),              \
106                                 (nla_type_), (nla_type_str_),           \
107                                 plen, (pattern_), plen,                 \
108                                 (fallback_func)((pattern_), plen));     \
109                 /* short read of sizeof(obj_) */                        \
110                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
111                         (init_msg_), (print_msg_),                      \
112                         (nla_type_), (nla_type_str_),                   \
113                         sizeof(obj_),                                   \
114                         (pattern_), (minsz_) - 1,                       \
115                         printf("%p",                                    \
116                                RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))));  \
117                 /* sizeof(obj_) */                                      \
118                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
119                         (init_msg_), (print_msg_),                      \
120                         (nla_type_), (nla_type_str_),                   \
121                         sizeof(obj_),                                   \
122                         &(obj_), sizeof(obj_),                          \
123                         __VA_ARGS__);                                   \
124         } while (0)
125
126 #define TEST_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_,                      \
127                               init_msg_, print_msg_,                    \
128                               nla_type_,                                \
129                               pattern_, obj_, minsz_, fallback_func, ...) \
130         TEST_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),               \
131                                (init_msg_), (print_msg_),               \
132                                (nla_type_), #nla_type_,                 \
133                                (pattern_), (obj_), (minsz_),            \
134                                (fallback_func), __VA_ARGS__)
135
136 #define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_,                         \
137                            init_msg_, print_msg_,                       \
138                            nla_type_, pattern_, obj_, ...)              \
139         TEST_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),               \
140                                (init_msg_), (print_msg_),               \
141                                (nla_type_), #nla_type_,                 \
142                                (pattern_), (obj_), sizeof(obj_),        \
143                                print_quoted_hex, __VA_ARGS__)
144
145 #define TEST_NLATTR_OBJECT_MINSZ(fd_, nlh0_, hdrlen_,                   \
146                            init_msg_, print_msg_,                       \
147                            nla_type_, pattern_, obj_, minsz_, ...)      \
148         TEST_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),               \
149                                (init_msg_), (print_msg_),               \
150                                (nla_type_), #nla_type_,                 \
151                                (pattern_), (obj_), (minsz_),            \
152                                print_quoted_hex, __VA_ARGS__)
153
154 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_,                          \
155                           init_msg_, print_msg_,                        \
156                           nla_type_, pattern_, obj_, print_elem_)       \
157         do {                                                            \
158                 const unsigned int plen =                               \
159                         sizeof((obj_)[0]) - 1 > DEFAULT_STRLEN          \
160                         ? DEFAULT_STRLEN : (int) sizeof((obj_)[0]) - 1; \
161                 /* len < sizeof((obj_)[0]) */                           \
162                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
163                         (init_msg_), (print_msg_),                      \
164                         (nla_type_), #nla_type_,                        \
165                         plen, (pattern_), plen,                         \
166                         print_quoted_hex((pattern_), plen));            \
167                 /* sizeof((obj_)[0]) < len < sizeof(obj_) */            \
168                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
169                         (init_msg_), (print_msg_),                      \
170                         (nla_type_), #nla_type_,                        \
171                         sizeof(obj_) - 1,                               \
172                         &(obj_), sizeof(obj_) - 1,                      \
173                         printf("[");                                    \
174                         size_t i;                                       \
175                         for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {    \
176                                 if (i) printf(", ");                    \
177                                 (print_elem_)(&(obj_)[i], i);           \
178                         }                                               \
179                         printf("]"));                                   \
180                 /* short read of sizeof(obj_) */                        \
181                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
182                         (init_msg_), (print_msg_),                      \
183                         (nla_type_), #nla_type_,                        \
184                         sizeof(obj_),                                   \
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(", ... /* %p */]",                       \
193                                RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))     \
194                                 + sizeof(obj_) - sizeof((obj_)[0])));   \
195                 /* sizeof(obj_) */                                      \
196                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
197                         (init_msg_), (print_msg_),                      \
198                         (nla_type_), #nla_type_,                        \
199                         sizeof(obj_),                                   \
200                         &(obj_), sizeof(obj_),                          \
201                         printf("[");                                    \
202                         size_t i;                                       \
203                         for (i = 0; i < ARRAY_SIZE(obj_); ++i) {        \
204                                 if (i) printf(", ");                    \
205                                 (print_elem_)(&(obj_)[i], i);           \
206                         }                                               \
207                         printf("]"));                                   \
208         } while (0)
209
210 #define TEST_NESTED_NLATTR_OBJECT_EX_(fd_, nlh0_, hdrlen_,              \
211                                       init_msg_, print_msg_,            \
212                                       nla_type_, nla_type_str_,         \
213                                       pattern_, obj_, fallback_func,    \
214                                       depth_, ...)      \
215         do {                                                            \
216                 const unsigned int plen =                               \
217                         sizeof(obj_) - 1 > DEFAULT_STRLEN               \
218                         ? DEFAULT_STRLEN : (int) sizeof(obj_) - 1;      \
219                 /* len < sizeof(obj_) */                                \
220                 if (plen > 0)                                           \
221                         TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_, \
222                                 (hdrlen_) + NLA_HDRLEN * depth_,        \
223                                 (init_msg_), (print_msg_),              \
224                                 (nla_type_), (nla_type_str_),           \
225                                 plen, (pattern_), plen,                 \
226                                 (fallback_func)((pattern_), plen);      \
227                                 size_t i;                               \
228                                 for (i = 0; i < depth_; ++i)            \
229                                         printf("}"));                   \
230                 /* short read of sizeof(obj_) */                        \
231                 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,      \
232                         (hdrlen_) + NLA_HDRLEN * depth_,                \
233                         (init_msg_), (print_msg_),                      \
234                         (nla_type_), (nla_type_str_),                   \
235                         sizeof(obj_),                                   \
236                         (pattern_), sizeof(obj_) - 1,                   \
237                         printf("%p", RTA_DATA(TEST_NLATTR_nla));        \
238                         size_t i;                                       \
239                         for (i = 0; i < depth_; ++i)                    \
240                                 printf("}"));                           \
241                 /* sizeof(obj_) */                                      \
242                 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,      \
243                         (hdrlen_) + NLA_HDRLEN * depth_,                \
244                         (init_msg_), (print_msg_),                      \
245                         (nla_type_), (nla_type_str_),                   \
246                         sizeof(obj_),                                   \
247                         &(obj_), sizeof(obj_),                          \
248                         __VA_ARGS__;                                    \
249                         size_t i;                                       \
250                         for (i = 0; i < depth_; ++i)                    \
251                                 printf("}"));                           \
252         } while (0)
253
254 #define TEST_NESTED_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_,               \
255                                      init_msg_, print_msg_,             \
256                                      nla_type_, pattern_, obj_,         \
257                                      depth_, ...)                       \
258         TEST_NESTED_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),        \
259                                       (init_msg_), (print_msg_),        \
260                                       (nla_type_), #nla_type_,          \
261                                       (pattern_), (obj_),               \
262                                       print_quoted_hex, (depth_),       \
263                                       __VA_ARGS__)
264
265 #define TEST_NESTED_NLATTR_OBJECT(fd_, nlh0_, hdrlen_,                  \
266                                   init_msg_, print_msg_,                \
267                                   nla_type_, pattern_, obj_, ...)       \
268         TEST_NESTED_NLATTR_OBJECT_EX_((fd_), (nlh0_), (hdrlen_),        \
269                                       (init_msg_), (print_msg_),        \
270                                       (nla_type_), #nla_type_,          \
271                                       (pattern_), (obj_),               \
272                                       print_quoted_hex, 1,              \
273                                       __VA_ARGS__)
274
275 #define TEST_NESTED_NLATTR_ARRAY_EX(fd_, nlh0_, hdrlen_,                \
276                                  init_msg_, print_msg_,                 \
277                                  nla_type_, pattern_, obj_, depth_,     \
278                                  print_elem_)                           \
279         do {                                                            \
280                 const unsigned int plen =                               \
281                         sizeof((obj_)[0]) - 1 > DEFAULT_STRLEN          \
282                         ? DEFAULT_STRLEN : (int) sizeof((obj_)[0]) - 1; \
283                 /* len < sizeof((obj_)[0]) */                           \
284                 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,      \
285                         (hdrlen_) + NLA_HDRLEN * depth_,                \
286                         (init_msg_), (print_msg_),                      \
287                         (nla_type_), #nla_type_,                        \
288                         plen, (pattern_), plen,                         \
289                         print_quoted_hex((pattern_), plen);             \
290                         for (size_t i = 0; i < depth_; ++i)             \
291                                 printf("}"));                           \
292                 /* sizeof((obj_)[0]) < len < sizeof(obj_) */            \
293                 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,      \
294                         (hdrlen_) + NLA_HDRLEN * depth_,                \
295                         (init_msg_), (print_msg_),                      \
296                         (nla_type_), #nla_type_,                        \
297                         sizeof(obj_) - 1,                               \
298                         &(obj_), sizeof(obj_) - 1,                      \
299                         printf("[");                                    \
300                         size_t i;                                       \
301                         for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {    \
302                                 if (i) printf(", ");                    \
303                                 (print_elem_)(&(obj_)[i], i);           \
304                         }                                               \
305                         printf("]");                                    \
306                         for (i = 0; i < depth_; ++i)                    \
307                                 printf("}"));                           \
308                 /* short read of sizeof(obj_) */                        \
309                 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,      \
310                         (hdrlen_) + NLA_HDRLEN * depth_,                \
311                         (init_msg_), (print_msg_),                      \
312                         (nla_type_), #nla_type_,                        \
313                         sizeof(obj_),                                   \
314                         &(obj_), sizeof(obj_) - 1,                      \
315                         printf("[");                                    \
316                         size_t i;                                       \
317                         for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {    \
318                                 if (i) printf(", ");                    \
319                                 (print_elem_)(&(obj_)[i], i);           \
320                         }                                               \
321                         printf(", ... /* %p */]",                       \
322                                RTA_DATA(TEST_NLATTR_nla)                \
323                                 + sizeof(obj_) - sizeof((obj_)[0]));    \
324                         for (i = 0; i < depth_; ++i)                    \
325                                 printf("}"));                           \
326                 /* sizeof(obj_) */                                      \
327                 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_,      \
328                         (hdrlen_) + NLA_HDRLEN * depth_,                \
329                         (init_msg_), (print_msg_),                      \
330                         (nla_type_), #nla_type_,                        \
331                         sizeof(obj_),                                   \
332                         &(obj_), sizeof(obj_),                          \
333                         printf("[");                                    \
334                         size_t i;                                       \
335                         for (i = 0; i < ARRAY_SIZE(obj_); ++i) {        \
336                                 if (i) printf(", ");                    \
337                                 (print_elem_)(&(obj_)[i], i);           \
338                         }                                               \
339                         printf("]");                                    \
340                         for (i = 0; i < depth_; ++i)                    \
341                                 printf("}"));                           \
342         } while (0)
343
344 #define TEST_NESTED_NLATTR_ARRAY(fd_, nlh0_, hdrlen_,                   \
345                                  init_msg_, print_msg_,                 \
346                                  nla_type_, pattern_, obj_, print_elem_)\
347         TEST_NESTED_NLATTR_ARRAY_EX((fd_), (nlh0_), (hdrlen_),          \
348                                     (init_msg_), (print_msg_),          \
349                                     nla_type_, (pattern_), (obj_), 1,   \
350                                     (print_elem_))