2017-06-30 21:38:49 +00:00
/*
2018-06-14 11:00:00 +00:00
* Copyright ( c ) 2017 - 2018 The strace developers .
2017-06-30 21:38:49 +00:00
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
* 3. The name of the author may not be used to endorse or promote products
* derived from this software without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR ` ` AS IS ' ' AND ANY EXPRESS OR
* IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE IMPLIED WARRANTIES
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED .
* IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT , INDIRECT ,
* INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL DAMAGES ( INCLUDING , BUT
* NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES ; LOSS OF USE ,
* DATA , OR PROFITS ; OR BUSINESS INTERRUPTION ) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT LIABILITY , OR TORT
* ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE .
*/
# include "tests.h"
2017-07-01 13:14:49 +00:00
# include "print_fields.h"
2017-06-30 21:38:49 +00:00
# include <stdio.h>
2017-08-15 22:34:46 +00:00
# include <stdint.h>
2017-06-30 21:38:49 +00:00
# include <string.h>
# include <sys/socket.h>
# include "netlink.h"
# include <linux/rtnetlink.h>
static void
init_nlattr ( struct nlattr * const nla ,
const uint16_t nla_len ,
const uint16_t nla_type ,
const void * const src ,
const size_t n )
{
SET_STRUCT ( struct nlattr , nla ,
. nla_len = nla_len ,
. nla_type = nla_type ,
) ;
memcpy ( RTA_DATA ( nla ) , src , n ) ;
}
static void
2018-06-10 12:46:19 +02:00
print_nlattr ( const unsigned int nla_len , const char * const nla_type , bool add_data )
2017-06-30 21:38:49 +00:00
{
2018-06-10 12:46:19 +02:00
printf ( " , %s{{nla_len=%u, nla_type=%s}, " ,
add_data ? " [ " : " " , nla_len , nla_type ) ;
2017-06-30 21:38:49 +00:00
}
2018-06-10 12:46:19 +02:00
# define TEST_NLATTR_EX_(fd_, nlh0_, hdrlen_, \
2017-06-30 21:38:49 +00:00
init_msg_ , print_msg_ , \
nla_type_ , nla_type_str_ , \
2018-06-10 12:46:19 +02:00
nla_data_len_ , nla_total_len_ , \
src_ , slen_ , . . . ) \
2017-06-30 21:38:49 +00:00
do { \
struct nlmsghdr * const nlh = \
( nlh0_ ) - ( NLA_HDRLEN + ( slen_ ) ) ; \
2017-07-05 21:25:13 +08:00
struct nlattr * const TEST_NLATTR_nla = \
NLMSG_ATTR ( nlh , ( hdrlen_ ) ) ; \
2017-06-30 21:38:49 +00:00
const unsigned int nla_len = \
NLA_HDRLEN + ( nla_data_len_ ) ; \
const unsigned int msg_len = \
2018-06-10 12:46:19 +02:00
NLMSG_SPACE ( hdrlen_ ) + NLA_HDRLEN + ( nla_total_len_ ) ; \
2017-06-30 21:38:49 +00:00
\
( init_msg_ ) ( nlh , msg_len ) ; \
2017-07-05 21:25:13 +08:00
init_nlattr ( TEST_NLATTR_nla , nla_len , ( nla_type_ ) , \
2017-06-30 21:38:49 +00:00
( src_ ) , ( slen_ ) ) ; \
\
const char * const errstr = \
sprintrc ( sendto ( ( fd_ ) , nlh , msg_len , \
MSG_DONTWAIT , NULL , 0 ) ) ; \
\
printf ( " sendto(%d, { " , ( fd_ ) ) ; \
( print_msg_ ) ( msg_len ) ; \
2018-06-10 12:46:19 +02:00
print_nlattr ( nla_len , ( nla_type_str_ ) , \
( nla_total_len_ ) > ( nla_data_len_ ) ) ; \
2017-06-30 21:38:49 +00:00
\
{ __VA_ARGS__ ; } \
\
2018-06-10 12:46:19 +02:00
if ( ( nla_total_len_ ) > ( nla_data_len_ ) ) \
printf ( " ] " ) ; \
\
2017-06-30 21:38:49 +00:00
printf ( " }}, %u, MSG_DONTWAIT, NULL, 0) = %s \n " , \
msg_len , errstr ) ; \
} while ( 0 )
2018-06-10 12:46:19 +02:00
# define TEST_NLATTR_(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , nla_type_str_ , \
nla_data_len_ , src_ , slen_ , . . . ) \
TEST_NLATTR_EX_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , ( nla_type_str_ ) , \
( nla_data_len_ ) , ( nla_data_len_ ) , \
( src_ ) , ( slen_ ) , __VA_ARGS__ )
2017-06-30 21:38:49 +00:00
# define TEST_NLATTR(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , \
nla_data_len_ , src_ , slen_ , . . . ) \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
( nla_data_len_ ) , ( src_ ) , ( slen_ ) , __VA_ARGS__ )
2017-07-20 16:45:58 +08:00
# define TEST_NLATTR_OBJECT_EX_(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , nla_type_str_ , \
pattern_ , obj_ , fallback_func , . . . ) \
2017-06-30 21:38:49 +00:00
do { \
2017-07-04 14:21:18 +08:00
const unsigned int plen = \
sizeof ( obj_ ) - 1 > DEFAULT_STRLEN \
2017-07-03 15:14:54 +00:00
? DEFAULT_STRLEN : ( int ) sizeof ( obj_ ) - 1 ; \
2017-06-30 21:38:49 +00:00
/* len < sizeof(obj_) */ \
2018-05-23 18:45:43 +02:00
if ( plen > 0 ) \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , ( nla_type_str_ ) , \
plen , ( pattern_ ) , plen , \
( fallback_func ) ( ( pattern_ ) , plen ) ) ; \
2017-06-30 21:38:49 +00:00
/* short read of sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
2017-07-20 16:45:58 +08:00
( nla_type_ ) , ( nla_type_str_ ) , \
2017-06-30 21:38:49 +00:00
sizeof ( obj_ ) , \
( pattern_ ) , sizeof ( obj_ ) - 1 , \
printf ( " %p " , \
RTA_DATA ( NLMSG_ATTR ( nlh , ( hdrlen_ ) ) ) ) ) ; \
/* sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
2017-07-20 16:45:58 +08:00
( nla_type_ ) , ( nla_type_str_ ) , \
2017-06-30 21:38:49 +00:00
sizeof ( obj_ ) , \
& ( obj_ ) , sizeof ( obj_ ) , \
__VA_ARGS__ ) ; \
} while ( 0 )
2017-07-20 16:45:58 +08:00
# define TEST_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , \
pattern_ , obj_ , fallback_func , . . . ) \
TEST_NLATTR_OBJECT_EX_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
( pattern_ ) , ( obj_ ) , ( fallback_func ) , \
__VA_ARGS__ )
# define TEST_NLATTR_OBJECT(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , pattern_ , obj_ , . . . ) \
TEST_NLATTR_OBJECT_EX_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
( pattern_ ) , ( obj_ ) , print_quoted_hex , \
__VA_ARGS__ )
2017-06-30 21:38:49 +00:00
# define TEST_NLATTR_ARRAY(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , pattern_ , obj_ , print_elem_ ) \
do { \
2017-07-04 14:21:18 +08:00
const unsigned int plen = \
2017-07-03 15:14:54 +00:00
sizeof ( ( obj_ ) [ 0 ] ) - 1 > DEFAULT_STRLEN \
? DEFAULT_STRLEN : ( int ) sizeof ( ( obj_ ) [ 0 ] ) - 1 ; \
2017-06-30 21:38:49 +00:00
/* len < sizeof((obj_)[0]) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
2017-07-05 09:39:34 +08:00
plen , ( pattern_ ) , plen , \
2017-07-04 14:21:18 +08:00
print_quoted_hex ( ( pattern_ ) , plen ) ) ; \
2017-06-30 21:38:49 +00:00
/* sizeof((obj_)[0]) < len < sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
sizeof ( obj_ ) - 1 , \
& ( obj_ ) , sizeof ( obj_ ) - 1 , \
printf ( " [ " ) ; \
size_t i ; \
for ( i = 0 ; i < ARRAY_SIZE ( obj_ ) - 1 ; + + i ) { \
if ( i ) printf ( " , " ) ; \
2018-05-10 18:26:37 +02:00
( print_elem_ ) ( & ( obj_ ) [ i ] , i ) ; \
2017-06-30 21:38:49 +00:00
} \
printf ( " ] " ) ) ; \
/* short read of sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
sizeof ( obj_ ) , \
& ( obj_ ) , sizeof ( obj_ ) - 1 , \
printf ( " [ " ) ; \
size_t i ; \
for ( i = 0 ; i < ARRAY_SIZE ( obj_ ) - 1 ; + + i ) { \
if ( i ) printf ( " , " ) ; \
2018-05-10 18:26:37 +02:00
( print_elem_ ) ( & ( obj_ ) [ i ] , i ) ; \
2017-06-30 21:38:49 +00:00
} \
print_array: enhance printing of unfetchable object addresses
When umoven_func invocation fails to fetch data, it prints the faulty
address. If this happens to a subsequent umoven_func invocation,
the printed address may be undistinguishable from a valid data printed
by print_func, e.g. when the data is printed in a numeric form like
[0x1, 0x2, 0x3, 0xdefaced].
Fix this source of confusion by moving the printing of the faulty
address from umoven_func to print_array itself. This change renames
umoven_func to tfetch_mem_func and changes its semantics, so that
- tfetch_mem_func never prints anything;
- tfetch_mem_func returns true if the fetch succeeded,
and false otherwise.
* defs.h (print_array): Replace umoven_func argument with
tfetch_mem_func.
* util.c (print_array): Replace umoven_func argument with
tfetch_mem_func, document expected tfetch_mem_func return value
semantics. When tfetch_mem_func returns false, print either addr
or "... /* addr */" depending on the context (inside the array or not).
* bpf.c (print_ebpf_prog, print_bpf_prog_info,
BEGIN_BPF_CMD_DECODER(BPF_PROG_QUERY)): Replace umoven_or_printaddr
argument of print_array with tfetch_mem.
* bpf_filter.c (print_bpf_fprog): Likewise.
* btrfs.c (btrfs_print_logical_ino_container,
btrfs_print_ino_path_container, btrfs_print_qgroup_inherit,
btrfs_ioctl): Likewise.
* dm.c (dm_decode_dm_target_deps): Likewise.
* epoll.c (epoll_wait_common): Likewise.
* file_ioctl.c (file_ioctl): Likewise.
* ipc_sem.c (tprint_sembuf_array): Likewise.
* kexec.c (print_kexec_segments): Likewise.
* mem.c (SYS_FUNC(subpage_prot)): Likewise.
* net.c (print_getsockopt): Likewise.
* netlink.c (decode_nlmsgerr_attr_cookie): Likewise.
* netlink_netlink_diag.c (decode_netlink_diag_groups): Likewise.
* netlink_packet_diag.c (decode_packet_diag_mclist): Likewise.
* netlink_unix_diag.c (decode_unix_diag_inode): Likewise.
* nlattr.c (decode_nla_meminfo): Likewise.
* numa.c (print_nodemask, SYS_FUNC(move_pages),
* perf_ioctl.c (perf_ioctl_query_bpf): Likewise.
* poll.c (decode_poll_entering): Likewise.
* printsiginfo.c (print_siginfo_array): Likewise.
* rtnl_tc.c (decode_tca_stab_data): Likewise.
* sock.c (decode_ifconf): Likewise.
* uid.c (print_groups): Likewise.
* io.c (SYS_FUNC(io_submit), SYS_FUNC(io_getevents)): Replace
umoven_or_printaddr argument of print_array with tfetch_mem.
(tprint_iov_upto): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* v4l2.c (print_v4l2_format_fmt): Replace umoven_or_printaddr argument
of print_array with tfetch_mem.
(print_v4l2_ext_controls): Replace umoven_or_printaddr_ignore_syserror
with tfetch_mem_ignore_syserror.
* mmsghdr.c (fetch_struct_mmsghdr_or_printaddr): Rename
to fetch_struct_mmsghdr_for_print, do not print address, return bool.
(decode_mmsgvec): Replace fetch_struct_mmsghdr_or_printaddr
with fetch_struct_mmsghdr_for_print.
* tests/aio.c (main): Update expected output.
* tests/bpf.c (print_BPF_PROG_QUERY_attr5): Likewise.
* tests/ioctl_perf-success.c (main): Likewise.
* tests/ioctl_v4l2.c (main): Update expected output.
* tests/kexec_load.c (main): Likewise.
* tests/mmsg_name.c (test_mmsg_name): Update expected output.
* tests/move_pages.c (print_page_array, print_node_array): Likewise.
* tests/poll.c (print_pollfd_array_entering): Likewise.
* tests/preadv-pwritev.c (main): Likewise.
* tests/preadv2-pwritev2.c (dumpio): Likewise.
* tests/process_vm_readv_writev.c (print_iov): Likewise.
* tests/pwritev.c (print_iovec): Likewise.
* tests/readv.c (main): Likewise.
* tests/seccomp-filter-v.c
* tests/semop.c (main): Likewise.
* tests/set_mempolicy.c (print_nodes): Likewise.
* tests/setgroups.c (main): Likewise.
* tests/test_nlattr.h (print_nlattr) Likewise.
Co-Authored-by: Eugene Syromyatnikov <evgsyr@gmail.com>
2018-05-29 01:15:19 +00:00
printf ( " , ... /* %p */] " , \
2017-06-30 21:38:49 +00:00
RTA_DATA ( NLMSG_ATTR ( nlh , ( hdrlen_ ) ) ) \
2018-05-10 19:33:52 +02:00
+ sizeof ( obj_ ) - sizeof ( ( obj_ ) [ 0 ] ) ) ) ; \
2017-06-30 21:38:49 +00:00
/* sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
sizeof ( obj_ ) , \
& ( obj_ ) , sizeof ( obj_ ) , \
printf ( " [ " ) ; \
size_t i ; \
for ( i = 0 ; i < ARRAY_SIZE ( obj_ ) ; + + i ) { \
if ( i ) printf ( " , " ) ; \
2018-05-10 18:26:37 +02:00
( print_elem_ ) ( & ( obj_ ) [ i ] , i ) ; \
2017-06-30 21:38:49 +00:00
} \
printf ( " ] " ) ) ; \
} while ( 0 )
2017-08-29 21:04:19 +08:00
2017-09-09 09:30:01 +08:00
# define TEST_NESTED_NLATTR_OBJECT_EX_(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , nla_type_str_ , \
2018-06-10 12:49:20 +02:00
pattern_ , obj_ , fallback_func , \
depth_ , . . . ) \
2017-08-29 21:04:19 +08:00
do { \
const unsigned int plen = \
sizeof ( obj_ ) - 1 > DEFAULT_STRLEN \
? DEFAULT_STRLEN : ( int ) sizeof ( obj_ ) - 1 ; \
/* len < sizeof(obj_) */ \
2018-05-23 18:45:43 +02:00
if ( plen > 0 ) \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN * depth_ , \
( hdrlen_ ) + NLA_HDRLEN * depth_ , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , ( nla_type_str_ ) , \
plen , ( pattern_ ) , plen , \
2018-06-10 12:49:20 +02:00
( fallback_func ) ( ( pattern_ ) , plen ) ; \
2018-05-23 18:45:43 +02:00
size_t i ; \
for ( i = 0 ; i < depth_ ; + + i ) \
printf ( " } " ) ) ; \
2017-08-29 21:04:19 +08:00
/* short read of sizeof(obj_) */ \
2017-09-09 09:30:01 +08:00
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN * depth_ , \
( hdrlen_ ) + NLA_HDRLEN * depth_ , \
2017-08-29 21:04:19 +08:00
( init_msg_ ) , ( print_msg_ ) , \
2017-09-09 09:30:01 +08:00
( nla_type_ ) , ( nla_type_str_ ) , \
2017-08-29 21:04:19 +08:00
sizeof ( obj_ ) , \
( pattern_ ) , sizeof ( obj_ ) - 1 , \
2017-09-09 09:30:01 +08:00
printf ( " %p " , RTA_DATA ( TEST_NLATTR_nla ) ) ; \
size_t i ; \
for ( i = 0 ; i < depth_ ; + + i ) \
printf ( " } " ) ) ; \
2017-08-29 21:04:19 +08:00
/* sizeof(obj_) */ \
2017-09-09 09:30:01 +08:00
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN * depth_ , \
( hdrlen_ ) + NLA_HDRLEN * depth_ , \
2017-08-29 21:04:19 +08:00
( init_msg_ ) , ( print_msg_ ) , \
2017-09-09 09:30:01 +08:00
( nla_type_ ) , ( nla_type_str_ ) , \
2017-08-29 21:04:19 +08:00
sizeof ( obj_ ) , \
& ( obj_ ) , sizeof ( obj_ ) , \
2017-09-09 09:30:01 +08:00
__VA_ARGS__ ; \
size_t i ; \
for ( i = 0 ; i < depth_ ; + + i ) \
printf ( " } " ) ) ; \
2017-08-29 21:04:19 +08:00
} while ( 0 )
2017-09-04 21:40:06 +08:00
2017-09-09 09:30:01 +08:00
# define TEST_NESTED_NLATTR_OBJECT_EX(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , pattern_ , obj_ , \
depth_ , . . . ) \
TEST_NESTED_NLATTR_OBJECT_EX_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
2018-06-10 12:49:20 +02:00
( pattern_ ) , ( obj_ ) , \
print_quoted_hex , ( depth_ ) , \
2017-09-09 09:30:01 +08:00
__VA_ARGS__ )
# define TEST_NESTED_NLATTR_OBJECT(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , pattern_ , obj_ , . . . ) \
TEST_NESTED_NLATTR_OBJECT_EX_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
2018-06-10 12:49:20 +02:00
( pattern_ ) , ( obj_ ) , \
print_quoted_hex , 1 , \
2017-09-09 09:30:01 +08:00
__VA_ARGS__ )
2018-05-25 05:09:53 +02:00
# define TEST_NESTED_NLATTR_ARRAY_EX(fd_, nlh0_, hdrlen_, \
2017-09-04 21:40:06 +08:00
init_msg_ , print_msg_ , \
2018-05-25 05:09:53 +02:00
nla_type_ , pattern_ , obj_ , depth_ , \
print_elem_ ) \
2017-09-04 21:40:06 +08:00
do { \
const unsigned int plen = \
sizeof ( ( obj_ ) [ 0 ] ) - 1 > DEFAULT_STRLEN \
? DEFAULT_STRLEN : ( int ) sizeof ( ( obj_ ) [ 0 ] ) - 1 ; \
/* len < sizeof((obj_)[0]) */ \
2018-05-25 05:09:53 +02:00
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN * depth_ , \
( hdrlen_ ) + NLA_HDRLEN * depth_ , \
2017-09-04 21:40:06 +08:00
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
plen , ( pattern_ ) , plen , \
print_quoted_hex ( ( pattern_ ) , plen ) ; \
2018-05-25 05:09:53 +02:00
for ( size_t i = 0 ; i < depth_ ; + + i ) \
printf ( " } " ) ) ; \
2017-09-04 21:40:06 +08:00
/* sizeof((obj_)[0]) < len < sizeof(obj_) */ \
2018-05-25 05:09:53 +02:00
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN * depth_ , \
( hdrlen_ ) + NLA_HDRLEN * depth_ , \
2017-09-04 21:40:06 +08:00
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
sizeof ( obj_ ) - 1 , \
& ( obj_ ) , sizeof ( obj_ ) - 1 , \
printf ( " [ " ) ; \
size_t i ; \
for ( i = 0 ; i < ARRAY_SIZE ( obj_ ) - 1 ; + + i ) { \
if ( i ) printf ( " , " ) ; \
2018-05-25 05:08:04 +02:00
( print_elem_ ) ( & ( obj_ ) [ i ] , i ) ; \
2017-09-04 21:40:06 +08:00
} \
2018-05-25 05:09:53 +02:00
printf ( " ] " ) ; \
for ( i = 0 ; i < depth_ ; + + i ) \
printf ( " } " ) ) ; \
2017-09-04 21:40:06 +08:00
/* short read of sizeof(obj_) */ \
2018-05-25 05:09:53 +02:00
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN * depth_ , \
( hdrlen_ ) + NLA_HDRLEN * depth_ , \
2017-09-04 21:40:06 +08:00
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
sizeof ( obj_ ) , \
& ( obj_ ) , sizeof ( obj_ ) - 1 , \
printf ( " [ " ) ; \
size_t i ; \
for ( i = 0 ; i < ARRAY_SIZE ( obj_ ) - 1 ; + + i ) { \
if ( i ) printf ( " , " ) ; \
2018-05-25 05:08:04 +02:00
( print_elem_ ) ( & ( obj_ ) [ i ] , i ) ; \
2017-09-04 21:40:06 +08:00
} \
2018-05-25 05:09:53 +02:00
printf ( " , ... /* %p */] " , \
2017-09-04 21:40:06 +08:00
RTA_DATA ( TEST_NLATTR_nla ) \
2018-05-25 05:09:53 +02:00
+ sizeof ( obj_ ) - sizeof ( ( obj_ ) [ 0 ] ) ) ; \
for ( i = 0 ; i < depth_ ; + + i ) \
printf ( " } " ) ) ; \
2017-09-04 21:40:06 +08:00
/* sizeof(obj_) */ \
2018-05-25 05:09:53 +02:00
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN * depth_ , \
( hdrlen_ ) + NLA_HDRLEN * depth_ , \
2017-09-04 21:40:06 +08:00
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
sizeof ( obj_ ) , \
& ( obj_ ) , sizeof ( obj_ ) , \
printf ( " [ " ) ; \
size_t i ; \
for ( i = 0 ; i < ARRAY_SIZE ( obj_ ) ; + + i ) { \
if ( i ) printf ( " , " ) ; \
2018-05-25 05:08:04 +02:00
( print_elem_ ) ( & ( obj_ ) [ i ] , i ) ; \
2017-09-04 21:40:06 +08:00
} \
2018-05-25 05:09:53 +02:00
printf ( " ] " ) ; \
for ( i = 0 ; i < depth_ ; + + i ) \
printf ( " } " ) ) ; \
2017-09-04 21:40:06 +08:00
} while ( 0 )
2018-05-25 05:09:53 +02:00
# define TEST_NESTED_NLATTR_ARRAY(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , pattern_ , obj_ , print_elem_ ) \
TEST_NESTED_NLATTR_ARRAY_EX ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
nla_type_ , ( pattern_ ) , ( obj_ ) , 1 , \
( print_elem_ ) )