1 #include "tests.h"
2 #include "print_fields.h"
3 
4 #include <stdio.h>
5 #include <stdint.h>
6 #include <string.h>
7 #include <sys/socket.h>
8 #include "netlink.h"
9 
10 #define TEST_NETLINK_(fd_, nlh0_,					\
11 		      type_, type_str_,					\
12 		      flags_, flags_str_,				\
13 		      data_len_, src_, slen_, ...)			\
14 	do {								\
15 		struct nlmsghdr *const TEST_NETLINK_nlh =		\
16 			(nlh0_) - (slen_);				\
17 		const unsigned int msg_len =				\
18 			NLMSG_HDRLEN + (data_len_);			\
19 									\
20 		SET_STRUCT(struct nlmsghdr, TEST_NETLINK_nlh,		\
21 			.nlmsg_len = msg_len,				\
22 			.nlmsg_type = (type_),				\
23 			.nlmsg_flags = (flags_)				\
24 		);							\
25 		memcpy(NLMSG_DATA(TEST_NETLINK_nlh), (src_), (slen_));	\
26 									\
27 		const char *const errstr =				\
28 			sprintrc(sendto((fd_), TEST_NETLINK_nlh,	\
29 					msg_len, MSG_DONTWAIT,		\
30 					NULL, 0));			\
31 									\
32 		printf("sendto(%d, {{len=%u, type=%s"			\
33 		       ", flags=%s, seq=0, pid=0}, ",			\
34 		       (fd_), msg_len, (type_str_), (flags_str_));	\
35 									\
36 		{ __VA_ARGS__; }					\
37 									\
38 		printf("}, %u, MSG_DONTWAIT, NULL, 0) = %s\n",		\
39 		       msg_len, errstr);				\
40 	} while (0)
41 
42 #define TEST_NETLINK(fd_, nlh0_, type_, flags_,				\
43 		     data_len_, src_, slen_, ...)			\
44 	TEST_NETLINK_((fd_), (nlh0_),					\
45 		      (type_), #type_,					\
46 		      (flags_), #flags_,				\
47 		      (data_len_), (src_), (slen_), __VA_ARGS__)
48 
49 #define TEST_NETLINK_OBJECT_EX_(fd_, nlh0_,				\
50 				type_, type_str_,			\
51 				flags_, flags_str_,			\
52 				obj_, fallback_func, ...)		\
53 	do {								\
54 		char pattern[DEFAULT_STRLEN];				\
55 		fill_memory_ex(pattern, sizeof(pattern),		\
56 			       'a', 'z' - 'a' + 1);			\
57 		const unsigned int plen =				\
58 			sizeof(obj_) - 1 > DEFAULT_STRLEN		\
59 			? DEFAULT_STRLEN : (int) sizeof(obj_) - 1;	\
60 		/* len < sizeof(obj_) */				\
61 		TEST_NETLINK_((fd_), (nlh0_),				\
62 			      (type_), (type_str_),			\
63 			      (flags_), (flags_str_),			\
64 			      plen, pattern, plen,			\
65 			      (fallback_func)(pattern, plen));		\
66 		/* short read of sizeof(obj_) */			\
67 		TEST_NETLINK_((fd_), (nlh0_),				\
68 			      (type_), (type_str_),			\
69 			      (flags_), (flags_str_),			\
70 			      sizeof(obj_),				\
71 			      pattern, plen,				\
72 			      printf("%p",				\
73 				     NLMSG_DATA(TEST_NETLINK_nlh)));	\
74 		/* sizeof(obj_) */					\
75 		TEST_NETLINK_((fd_), (nlh0_),				\
76 			      (type_), (type_str_),			\
77 			      (flags_), (flags_str_),			\
78 			      sizeof(obj_),				\
79 			      &(obj_), sizeof(obj_),			\
80 			      __VA_ARGS__);				\
81 	} while (0)
82 
83 #define TEST_NETLINK_OBJECT_EX(fd_, nlh0_,				\
84 			       type_, flags_,				\
85 			       obj_, fallback_func, ...)		\
86 	TEST_NETLINK_OBJECT_EX_((fd_), (nlh0),				\
87 				(type_), #type_,			\
88 				(flags_), #flags_,			\
89 				(obj_), (fallback_func), __VA_ARGS__)
90 
91 #define TEST_NETLINK_OBJECT(fd_, nlh0_,					\
92 			    type_, flags_,				\
93 			    obj_, ...)					\
94 	TEST_NETLINK_OBJECT_EX_((fd_), (nlh0),				\
95 				(type_), #type_,			\
96 				(flags_), #flags_,			\
97 				(obj_), print_quoted_hex, __VA_ARGS__)
98