1 /*
2 * Copyright (c) 2017-2021 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
17 #define TEST_NETLINK_(fd_, nlh0_, \
18 type_, type_str_, \
19 flags_, flags_str_, \
20 data_len_, src_, slen_, ...) \
21 do { \
22 struct nlmsghdr *const TEST_NETLINK_nlh = \
23 (nlh0_) - (slen_); \
24 const unsigned int msg_len = \
25 NLMSG_HDRLEN + (data_len_); \
26 \
27 SET_STRUCT(struct nlmsghdr, TEST_NETLINK_nlh, \
28 .nlmsg_len = msg_len, \
29 .nlmsg_type = (type_), \
30 .nlmsg_flags = (flags_) \
31 ); \
32 memcpy(NLMSG_DATA(TEST_NETLINK_nlh), (src_), (slen_)); \
33 \
34 const char *const errstr = \
35 sprintrc(sendto((fd_), TEST_NETLINK_nlh, \
36 msg_len, MSG_DONTWAIT, \
37 NULL, 0)); \
38 \
39 printf("sendto(%d, [{nlmsg_len=%u, nlmsg_type=%s" \
40 ", nlmsg_flags=%s, nlmsg_seq=0, nlmsg_pid=0}, ", \
41 (fd_), msg_len, (type_str_), (flags_str_)); \
42 \
43 { __VA_ARGS__; } \
44 \
45 printf("], %u, " XLAT_FMT ", NULL, 0) = %s\n", \
46 msg_len, XLAT_ARGS(MSG_DONTWAIT), errstr); \
47 } while (0)
48
49 #define TEST_NETLINK(fd_, nlh0_, type_, flags_, \
50 data_len_, src_, slen_, ...) \
51 TEST_NETLINK_((fd_), (nlh0_), \
52 (type_), #type_, \
53 (flags_), #flags_, \
54 (data_len_), (src_), (slen_), __VA_ARGS__)
55
56 #define TEST_NETLINK_OBJECT_EX_(fd_, nlh0_, \
57 type_, type_str_, \
58 flags_, flags_str_, \
59 obj_, fallback_func, ...) \
60 do { \
61 char pattern[DEFAULT_STRLEN]; \
62 fill_memory_ex(pattern, sizeof(pattern), \
63 'a', 'z' - 'a' + 1); \
64 const unsigned int plen = \
65 sizeof(obj_) - 1 > DEFAULT_STRLEN \
66 ? DEFAULT_STRLEN : (int) sizeof(obj_) - 1; \
67 /* len < sizeof(obj_) */ \
68 TEST_NETLINK_((fd_), (nlh0_), \
69 (type_), (type_str_), \
70 (flags_), (flags_str_), \
71 plen, pattern, plen, \
72 (fallback_func)(pattern, plen)); \
73 /* short read of sizeof(obj_) */ \
74 TEST_NETLINK_((fd_), (nlh0_), \
75 (type_), (type_str_), \
76 (flags_), (flags_str_), \
77 sizeof(obj_), \
78 pattern, plen, \
79 printf("%p", \
80 NLMSG_DATA(TEST_NETLINK_nlh))); \
81 /* sizeof(obj_) */ \
82 TEST_NETLINK_((fd_), (nlh0_), \
83 (type_), (type_str_), \
84 (flags_), (flags_str_), \
85 sizeof(obj_), \
86 &(obj_), sizeof(obj_), \
87 __VA_ARGS__); \
88 } while (0)
89
90 #define TEST_NETLINK_OBJECT_EX(fd_, nlh0_, \
91 type_, flags_, \
92 obj_, fallback_func, ...) \
93 TEST_NETLINK_OBJECT_EX_((fd_), (nlh0), \
94 (type_), #type_, \
95 (flags_), #flags_, \
96 (obj_), (fallback_func), __VA_ARGS__)
97
98 #define TEST_NETLINK_OBJECT(fd_, nlh0_, \
99 type_, flags_, \
100 obj_, ...) \
101 TEST_NETLINK_OBJECT_EX_((fd_), (nlh0), \
102 (type_), #type_, \
103 (flags_), #flags_, \
104 (obj_), print_quoted_hex, __VA_ARGS__)