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 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; \
72 (init_msg_)(nlh, msg_len); \
73 init_nlattr(TEST_NLATTR_nla, nla_len, (nla_type_), \
76 const char *const errstr = \
77 sprintrc(sendto((fd_), nlh, msg_len, \
78 MSG_DONTWAIT, NULL, 0)); \
80 printf("sendto(%d, {", (fd_)); \
81 (print_msg_)(msg_len); \
82 print_nlattr(nla_len, (nla_type_str_)); \
86 printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n", \
90 #define TEST_NLATTR(fd_, nlh0_, hdrlen_, \
91 init_msg_, print_msg_, \
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__)
99 #define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_, \
100 init_msg_, print_msg_, \
101 nla_type_, pattern_, obj_, ...) \
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_, \
117 (pattern_), sizeof(obj_) - 1, \
119 RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))))); \
121 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
122 (init_msg_), (print_msg_), \
123 (nla_type_), #nla_type_, \
125 &(obj_), sizeof(obj_), \
129 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_, \
130 init_msg_, print_msg_, \
131 nla_type_, pattern_, obj_, print_elem_) \
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_, \
147 &(obj_), sizeof(obj_) - 1, \
150 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
151 if (i) printf(", "); \
152 (print_elem_)(&(obj_)[i]); \
155 /* short read of sizeof(obj_) */ \
156 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
157 (init_msg_), (print_msg_), \
158 (nla_type_), #nla_type_, \
160 &(obj_), sizeof(obj_) - 1, \
163 for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) { \
164 if (i) printf(", "); \
165 (print_elem_)(&(obj_)[i]); \
168 RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_))) \
169 + sizeof((obj_)[0]))); \
171 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_), \
172 (init_msg_), (print_msg_), \
173 (nla_type_), #nla_type_, \
175 &(obj_), sizeof(obj_), \
178 for (i = 0; i < ARRAY_SIZE(obj_); ++i) { \
179 if (i) printf(", "); \
180 (print_elem_)(&(obj_)[i]); \