]> granicus.if.org Git - strace/blob - tests/test_nlattr.h
Introduce generic STRINGIFY and STRINGIFY_VAL macros
[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 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;                 \
70                                                                         \
71                 (init_msg_)(nlh, msg_len);                              \
72                 init_nlattr(nla, nla_len, (nla_type_),                  \
73                            (src_), (slen_));                            \
74                                                                         \
75                 const char *const errstr =                              \
76                         sprintrc(sendto((fd_), nlh, msg_len,            \
77                                         MSG_DONTWAIT, NULL, 0));        \
78                                                                         \
79                 printf("sendto(%d, {", (fd_));                          \
80                 (print_msg_)(msg_len);                                  \
81                 print_nlattr(nla_len, (nla_type_str_));                 \
82                                                                         \
83                 { __VA_ARGS__; }                                        \
84                                                                         \
85                 printf("}}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",         \
86                        msg_len, errstr);                                \
87         } while (0)
88
89 #define TEST_NLATTR(fd_, nlh0_, hdrlen_,                                \
90                     init_msg_, print_msg_,                              \
91                     nla_type_,                                          \
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__)
97
98 #define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_,                         \
99                            init_msg_, print_msg_,                       \
100                            nla_type_, pattern_, obj_, ...)              \
101         do {                                                            \
102                 /* len < sizeof(obj_) */                                \
103                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
104                         (init_msg_), (print_msg_),                      \
105                         (nla_type_), #nla_type_,                        \
106                         sizeof(obj_) - 1,                               \
107                         (pattern_), sizeof(obj_) - 1,                   \
108                         printf("\"%.*s\"",                              \
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_,                        \
114                         sizeof(obj_),                                   \
115                         (pattern_), sizeof(obj_) - 1,                   \
116                         printf("%p",                                    \
117                                RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))));  \
118                 /* sizeof(obj_) */                                      \
119                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
120                         (init_msg_), (print_msg_),                      \
121                         (nla_type_), #nla_type_,                        \
122                         sizeof(obj_),                                   \
123                         &(obj_), sizeof(obj_),                          \
124                         __VA_ARGS__);                                   \
125         } while (0)
126
127 #define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_,                          \
128                           init_msg_, print_msg_,                        \
129                           nla_type_, pattern_, obj_, print_elem_)       \
130         do {                                                            \
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,              \
137                         printf("\"%.*s\"",                              \
138                                (int) sizeof((obj_)[0]) - 1,             \
139                                (pattern_)));                            \
140                 /* sizeof((obj_)[0]) < len < sizeof(obj_) */            \
141                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
142                         (init_msg_), (print_msg_),                      \
143                         (nla_type_), #nla_type_,                        \
144                         sizeof(obj_) - 1,                               \
145                         &(obj_), sizeof(obj_) - 1,                      \
146                         printf("[");                                    \
147                         size_t i;                                       \
148                         for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {    \
149                                 if (i) printf(", ");                    \
150                                 (print_elem_)(&(obj_)[i]);              \
151                         }                                               \
152                         printf("]"));                                   \
153                 /* short read of sizeof(obj_) */                        \
154                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
155                         (init_msg_), (print_msg_),                      \
156                         (nla_type_), #nla_type_,                        \
157                         sizeof(obj_),                                   \
158                         &(obj_), sizeof(obj_) - 1,                      \
159                         printf("[");                                    \
160                         size_t i;                                       \
161                         for (i = 0; i < ARRAY_SIZE(obj_) - 1; ++i) {    \
162                                 if (i) printf(", ");                    \
163                                 (print_elem_)(&(obj_)[i]);              \
164                         }                                               \
165                         printf(", %p]",                                 \
166                                RTA_DATA(NLMSG_ATTR(nlh, (hdrlen_)))     \
167                                 + sizeof((obj_)[0])));                  \
168                 /* sizeof(obj_) */                                      \
169                 TEST_NLATTR_((fd_), (nlh0_), (hdrlen_),                 \
170                         (init_msg_), (print_msg_),                      \
171                         (nla_type_), #nla_type_,                        \
172                         sizeof(obj_),                                   \
173                         &(obj_), sizeof(obj_),                          \
174                         printf("[");                                    \
175                         size_t i;                                       \
176                         for (i = 0; i < ARRAY_SIZE(obj_); ++i) {        \
177                                 if (i) printf(", ");                    \
178                                 (print_elem_)(&(obj_)[i]);              \
179                         }                                               \
180                         printf("]"));                                   \
181         } while (0)