2 * Copyright (c) 2017-2018 The strace developers.
5 * SPDX-License-Identifier: GPL-2.0-or-later
9 #include "print_fields.h"
14 #include <sys/socket.h>
16 #include <linux/rtnetlink.h>
19 init_nlattr(struct nlattr *const nla,
20 const uint16_t nla_len,
21 const uint16_t nla_type,
22 const void *const src,
25 SET_STRUCT(struct nlattr, nla,
30 memcpy(RTA_DATA(nla), src, n);
34 print_nlattr(const unsigned int nla_len, const char *const nla_type, bool add_data)
36 printf(", %s{{nla_len=%u, nla_type=%s}, ",
37 add_data ? "[" : "", nla_len, nla_type);
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_, \
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_); \
55 (init_msg_)(nlh, msg_len); \
56 init_nlattr(TEST_NLATTR_nla, nla_len, (nla_type_), \
59 const char *const errstr = \
60 sprintrc(sendto((fd_), nlh, msg_len, \
61 MSG_DONTWAIT, NULL, 0)); \
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_)); \
70 if ((nla_total_len_) > (nla_data_len_)) \
73 printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", \
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__)
87 #define TEST_NLATTR(fd_, nlh0_, hdrlen_, \
88 init_msg_, print_msg_, \
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__)
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, ...) \
101 const unsigned int plen = MIN((minsz_) - 1, DEFAULT_STRLEN); \
102 /* len < sizeof(obj_) */ \
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_), \
114 (pattern_), (minsz_) - 1, \
116 RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))))); \
118 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
119 (init_msg_), (print_msg_), \
120 (nla_type_), (nla_type_str_), \
122 &(obj_), sizeof(obj_), \
126 #define TEST_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_, \
127 init_msg_, print_msg_, \
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__)
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__)
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__)
154 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_, \
155 init_msg_, print_msg_, \
156 nla_type_, pattern_, obj_, print_elem_) \
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_, \
172 &(obj_), sizeof(obj_) - 1, \
175 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
176 if (i) printf(", "); \
177 (print_elem_)(&(obj_)[i], i); \
180 /* short read of sizeof(obj_) */ \
181 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
182 (init_msg_), (print_msg_), \
183 (nla_type_), #nla_type_, \
185 &(obj_), sizeof(obj_) - 1, \
188 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
189 if (i) printf(", "); \
190 (print_elem_)(&(obj_)[i], i); \
192 printf(", ... /* %p */]", \
193 RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))) \
194 + sizeof(obj_) - sizeof((obj_)[0]))); \
196 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
197 (init_msg_), (print_msg_), \
198 (nla_type_), #nla_type_, \
200 &(obj_), sizeof(obj_), \
203 for (i = 0; i < ARRAY_SIZE(obj_); ++i) { \
204 if (i) printf(", "); \
205 (print_elem_)(&(obj_)[i], i); \
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, \
216 const unsigned int plen = \
217 sizeof(obj_) - 1 > DEFAULT_STRLEN \
218 ? DEFAULT_STRLEN : (int) sizeof(obj_) - 1; \
219 /* len < sizeof(obj_) */ \
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); \
228 for (i = 0; i < depth_; ++i) \
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_), \
236 (pattern_), sizeof(obj_) - 1, \
237 printf("%p", RTA_DATA(TEST_NLATTR_nla)); \
239 for (i = 0; i < depth_; ++i) \
242 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_, \
243 (hdrlen_) + NLA_HDRLEN * depth_, \
244 (init_msg_), (print_msg_), \
245 (nla_type_), (nla_type_str_), \
247 &(obj_), sizeof(obj_), \
250 for (i = 0; i < depth_; ++i) \
254 #define TEST_NESTED_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_, \
255 init_msg_, print_msg_, \
256 nla_type_, pattern_, obj_, \
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_), \
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, \
275 #define TEST_NESTED_NLATTR_ARRAY_EX(fd_, nlh0_, hdrlen_, \
276 init_msg_, print_msg_, \
277 nla_type_, pattern_, obj_, depth_, \
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) \
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_, \
298 &(obj_), sizeof(obj_) - 1, \
301 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
302 if (i) printf(", "); \
303 (print_elem_)(&(obj_)[i], i); \
306 for (i = 0; i < depth_; ++i) \
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_, \
314 &(obj_), sizeof(obj_) - 1, \
317 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
318 if (i) printf(", "); \
319 (print_elem_)(&(obj_)[i], i); \
321 printf(", ... /* %p */]", \
322 RTA_DATA(TEST_NLATTR_nla) \
323 + sizeof(obj_) - sizeof((obj_)[0])); \
324 for (i = 0; i < depth_; ++i) \
327 TEST_NLATTR_((fd_), (nlh0_) - NLA_HDRLEN * depth_, \
328 (hdrlen_) + NLA_HDRLEN * depth_, \
329 (init_msg_), (print_msg_), \
330 (nla_type_), #nla_type_, \
332 &(obj_), sizeof(obj_), \
335 for (i = 0; i < ARRAY_SIZE(obj_); ++i) { \
336 if (i) printf(", "); \
337 (print_elem_)(&(obj_)[i], i); \
340 for (i = 0; i < depth_; ++i) \
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, \