2017-06-30 21:38:49 +00:00
/*
* Copyright ( c ) 2017 The strace developers .
* 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
print_nlattr ( const unsigned int nla_len , const char * const nla_type )
{
printf ( " , {{nla_len=%u, nla_type=%s}, " , nla_len , nla_type ) ;
}
# define TEST_NLATTR_(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , nla_type_str_ , \
nla_data_len_ , src_ , slen_ , . . . ) \
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 = \
NLMSG_SPACE ( hdrlen_ ) + nla_len ; \
\
( 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 ) ; \
print_nlattr ( nla_len , ( nla_type_str_ ) ) ; \
\
{ __VA_ARGS__ ; } \
\
printf ( " }}, %u, MSG_DONTWAIT, NULL, 0) = %s \n " , \
msg_len , errstr ) ; \
} while ( 0 )
# 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_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) , ( hdrlen_ ) , \
( init_msg_ ) , ( print_msg_ ) , \
2017-07-20 16:45:58 +08:00
( nla_type_ ) , ( nla_type_str_ ) , \
2017-07-05 09:39:34 +08:00
plen , ( pattern_ ) , plen , \
2017-07-20 16:45:58 +08:00
( 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 ( " , " ) ; \
( print_elem_ ) ( & ( obj_ ) [ i ] ) ; \
} \
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 ( " , " ) ; \
( print_elem_ ) ( & ( obj_ ) [ i ] ) ; \
} \
printf ( " , %p] " , \
RTA_DATA ( NLMSG_ATTR ( nlh , ( hdrlen_ ) ) ) \
+ sizeof ( ( obj_ ) [ 0 ] ) ) ) ; \
/* 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 ( " , " ) ; \
( print_elem_ ) ( & ( obj_ ) [ i ] ) ; \
} \
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_ , \
pattern_ , obj_ , 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_) */ \
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
plen , ( pattern_ ) , plen , \
print_quoted_hex ( ( pattern_ ) , plen ) ; \
2017-09-09 09:30:01 +08: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_ , \
( pattern_ ) , ( obj_ ) , ( depth_ ) , \
__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_ , \
( pattern_ ) , ( obj_ ) , 1 , \
__VA_ARGS__ )
2017-09-04 21:40:06 +08:00
# define TEST_NESTED_NLATTR_ARRAY(fd_, nlh0_, hdrlen_, \
init_msg_ , print_msg_ , \
nla_type_ , pattern_ , obj_ , print_elem_ ) \
do { \
const unsigned int plen = \
sizeof ( ( obj_ ) [ 0 ] ) - 1 > DEFAULT_STRLEN \
? DEFAULT_STRLEN : ( int ) sizeof ( ( obj_ ) [ 0 ] ) - 1 ; \
/* len < sizeof((obj_)[0]) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN , \
( hdrlen_ ) + NLA_HDRLEN , \
( init_msg_ ) , ( print_msg_ ) , \
( nla_type_ ) , # nla_type_ , \
plen , ( pattern_ ) , plen , \
print_quoted_hex ( ( pattern_ ) , plen ) ; \
printf ( " } " ) ) ; \
/* sizeof((obj_)[0]) < len < sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN , \
( hdrlen_ ) + NLA_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 ( " , " ) ; \
( print_elem_ ) ( & ( obj_ ) [ i ] ) ; \
} \
printf ( " ]} " ) ) ; \
/* short read of sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN , \
( hdrlen_ ) + NLA_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 ( " , " ) ; \
( print_elem_ ) ( & ( obj_ ) [ i ] ) ; \
} \
printf ( " , %p]} " , \
RTA_DATA ( TEST_NLATTR_nla ) \
+ sizeof ( ( obj_ ) [ 0 ] ) ) ) ; \
/* sizeof(obj_) */ \
TEST_NLATTR_ ( ( fd_ ) , ( nlh0_ ) - NLA_HDRLEN , \
( hdrlen_ ) + NLA_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 ( " , " ) ; \
( print_elem_ ) ( & ( obj_ ) [ i ] ) ; \
} \
printf ( " ]} " ) ) ; \
} while ( 0 )