2 * Copyright (c) 2017 The strace developers.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
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.
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.
29 #include "print_fields.h"
33 #include <sys/socket.h>
35 #include <linux/rtnetlink.h>
38 init_nlattr(struct nlattr *const nla,
39 const uint16_t nla_len,
40 const uint16_t nla_type,
41 const void *const src,
44 SET_STRUCT(struct nlattr, nla,
49 memcpy(RTA_DATA(nla), src, n);
53 print_nlattr(const unsigned int nla_len, const char *const nla_type)
55 printf(", {{nla_len=%u, nla_type=%s}, ", nla_len, nla_type);
58 #define TEST_NLATTR_(fd_, nlh0_, hdrlen_, \
59 init_msg_, print_msg_, \
60 nla_type_, nla_type_str_, \
61 nla_data_len_, src_, slen_, ...) \
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; \
71 (init_msg_)(nlh, msg_len); \
72 init_nlattr(nla, nla_len, (nla_type_), \
75 const char *const errstr = \
76 sprintrc(sendto((fd_), nlh, msg_len, \
77 MSG_DONTWAIT, NULL, 0)); \
79 printf("sendto(%d, {", (fd_)); \
80 (print_msg_)(msg_len); \
81 print_nlattr(nla_len, (nla_type_str_)); \
85 printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", \
89 #define TEST_NLATTR(fd_, nlh0_, hdrlen_, \
90 init_msg_, print_msg_, \
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__)
98 #define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_, \
99 init_msg_, print_msg_, \
100 nla_type_, pattern_, obj_, ...) \
102 /* len < sizeof(obj_) */ \
103 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
104 (init_msg_), (print_msg_), \
105 (nla_type_), #nla_type_, \
107 (pattern_), sizeof(obj_) - 1, \
109 (int) sizeof(obj_) - 1, (pattern_))); \
110 /* short read of sizeof(obj_) */ \
111 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
112 (init_msg_), (print_msg_), \
113 (nla_type_), #nla_type_, \
115 (pattern_), sizeof(obj_) - 1, \
117 RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))))); \
119 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
120 (init_msg_), (print_msg_), \
121 (nla_type_), #nla_type_, \
123 &(obj_), sizeof(obj_), \
127 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_, \
128 init_msg_, print_msg_, \
129 nla_type_, pattern_, obj_, print_elem_) \
131 /* len < sizeof((obj_)[0]) */ \
132 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
133 (init_msg_), (print_msg_), \
134 (nla_type_), #nla_type_, \
135 sizeof((obj_)[0]) - 1, \
136 (pattern_), sizeof((obj_)[0]) - 1, \
138 (int) sizeof((obj_)[0]) - 1, \
140 /* sizeof((obj_)[0]) < len < sizeof(obj_) */ \
141 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
142 (init_msg_), (print_msg_), \
143 (nla_type_), #nla_type_, \
145 &(obj_), sizeof(obj_) - 1, \
148 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
149 if (i) printf(", "); \
150 (print_elem_)(&(obj_)[i]); \
153 /* short read of sizeof(obj_) */ \
154 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
155 (init_msg_), (print_msg_), \
156 (nla_type_), #nla_type_, \
158 &(obj_), sizeof(obj_) - 1, \
161 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
162 if (i) printf(", "); \
163 (print_elem_)(&(obj_)[i]); \
166 RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))) \
167 + sizeof((obj_)[0]))); \
169 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
170 (init_msg_), (print_msg_), \
171 (nla_type_), #nla_type_, \
173 &(obj_), sizeof(obj_), \
176 for (i = 0; i < ARRAY_SIZE(obj_); ++i) { \
177 if (i) printf(", "); \
178 (print_elem_)(&(obj_)[i]); \