2017-08-08 22:39:22 +08:00
/*
* Copyright ( c ) 2017 JingPiao Chen < chenjingpiao @ gmail . com >
2018-04-05 01:40:00 +00:00
* Copyright ( c ) 2017 - 2018 The strace developers .
2017-08-08 22:39:22 +08: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"
2018-04-08 23:48:56 +05:30
# include <string.h>
2017-08-08 22:39:22 +08:00
# include <stdio.h>
# include <sys/socket.h>
2018-04-08 23:48:56 +05:30
# include <arpa/inet.h>
2017-08-08 22:39:22 +08:00
# include "netlink.h"
2018-04-08 23:48:56 +05:30
# include "netlink_kobject_uevent.h"
2017-08-08 22:39:22 +08:00
2018-04-04 12:24:19 +00:00
static const char * errstr ;
static ssize_t
sys_send ( const int fd , const void * const buf , const size_t len )
{
const ssize_t rc = sendto ( fd , buf , len , MSG_DONTWAIT , NULL , 0 ) ;
errstr = sprintrc ( rc ) ;
return rc ;
}
2018-04-08 23:48:56 +05:30
static void
test_nlmsg_type_udev ( const int fd )
{
2018-04-11 15:41:40 +00:00
static const char extra [ ] = " 12345678 " ;
2018-04-08 23:48:56 +05:30
struct udev_monitor_netlink_header uh = {
. prefix = " libudev " ,
. magic = htonl ( 0xfeedcafe ) ,
. header_size = sizeof ( uh ) ,
. properties_off = 40 ,
. properties_len = 299 ,
. filter_subsystem_hash = htonl ( 0xc370b302 ) ,
. filter_devtype_hash = htonl ( 0x10800000 ) ,
. filter_tag_bloom_hi = htonl ( 0x2000400 ) ,
. filter_tag_bloom_lo = htonl ( 0x10800000 ) ,
} ;
2018-04-11 15:41:40 +00:00
const unsigned int extra_len = LENGTH_OF ( extra ) ;
const unsigned int uh_len = sizeof ( uh ) ;
2018-04-08 23:48:56 +05:30
2018-04-11 15:41:40 +00:00
char * const buf = tail_alloc ( uh_len + extra_len ) ;
memcpy ( buf + extra_len , & uh , uh_len ) ;
sys_send ( fd , buf + extra_len , uh_len ) ;
2018-04-08 23:48:56 +05:30
printf ( " sendto(%d, {{prefix= \" %s \" , magic=htonl(%#x) "
" , header_size=%u, properties_off=%u, properties_len=%u "
" , filter_subsystem_hash=htonl(%#x) "
" , filter_devtype_hash=htonl(%#x) "
" , filter_tag_bloom_hi=htonl(%#x) "
" , filter_tag_bloom_lo=htonl(%#x)}}, %u, MSG_DONTWAIT, NULL, "
" 0) = %s \n "
, fd , uh . prefix ,
ntohl ( uh . magic ) , uh . header_size , uh . properties_off ,
uh . properties_len , ntohl ( uh . filter_subsystem_hash ) ,
ntohl ( uh . filter_devtype_hash ) , ntohl ( uh . filter_tag_bloom_hi ) ,
2018-04-11 15:41:40 +00:00
ntohl ( uh . filter_tag_bloom_lo ) , uh_len , errstr ) ;
2018-04-08 23:48:56 +05:30
2018-04-11 15:41:40 +00:00
memcpy ( buf , & uh , uh_len ) ;
memcpy ( buf + uh_len , extra , extra_len ) ;
sys_send ( fd , buf , uh_len + extra_len ) ;
2018-04-08 23:48:56 +05:30
printf ( " sendto(%d, {{prefix= \" %s \" , magic=htonl(%#x) "
" , header_size=%u, properties_off=%u, properties_len=%u "
" , filter_subsystem_hash=htonl(%#x) "
" , filter_devtype_hash=htonl(%#x) "
" , filter_tag_bloom_hi=htonl(%#x) "
" , filter_tag_bloom_lo=htonl(%#x)}, "
, fd , uh . prefix ,
ntohl ( uh . magic ) , uh . header_size , uh . properties_off ,
uh . properties_len , ntohl ( uh . filter_subsystem_hash ) ,
ntohl ( uh . filter_devtype_hash ) , ntohl ( uh . filter_tag_bloom_hi ) ,
ntohl ( uh . filter_tag_bloom_lo ) ) ;
2018-04-11 15:41:40 +00:00
print_quoted_memory ( buf + uh_len , extra_len ) ;
2018-04-08 23:48:56 +05:30
printf ( " }, %u, MSG_DONTWAIT, NULL, 0) = %s \n " ,
2018-04-11 15:41:40 +00:00
uh_len + extra_len , errstr ) ;
2018-04-08 23:48:56 +05:30
2018-04-11 15:41:40 +00:00
memcpy ( buf + extra_len + 1 , & uh , uh_len - 1 ) ;
sys_send ( fd , buf + extra_len + 1 , uh_len ) ;
printf ( " sendto(%d, " , fd ) ;
print_quoted_memory ( & uh , MIN ( uh_len - 1 , DEFAULT_STRLEN ) ) ;
printf ( " %s, %u, MSG_DONTWAIT, NULL, 0) = %s \n " ,
( uh_len - 1 > DEFAULT_STRLEN ? " ... " : " " ) ,
uh_len , errstr ) ;
2018-04-08 23:48:56 +05:30
}
static void
test_nlmsg_type_kernel ( const int fd )
{
struct udev_monitor_netlink_header uh = {
. prefix = " change@ " ,
. magic = htonl ( 0xfeedcafe ) ,
. header_size = sizeof ( uh ) ,
. properties_off = 10 ,
. properties_len = 299 ,
. filter_subsystem_hash = htonl ( 0xfffffff ) ,
. filter_devtype_hash = htonl ( 0x10000000 ) ,
. filter_tag_bloom_hi = htonl ( 0x2000400 ) ,
} ;
2018-04-11 15:41:40 +00:00
const unsigned int uh_len = sizeof ( uh ) ;
2018-04-08 23:48:56 +05:30
2018-04-11 15:41:40 +00:00
TAIL_ALLOC_OBJECT_CONST_PTR ( struct udev_monitor_netlink_header , p ) ;
memcpy ( p , & uh , uh_len ) ;
sys_send ( fd , p , uh_len ) ;
2018-04-08 23:48:56 +05:30
printf ( " sendto(%d, " , fd ) ;
2018-04-11 15:41:40 +00:00
print_quoted_memory ( & uh , MIN ( uh_len , DEFAULT_STRLEN ) ) ;
printf ( " %s, %u, MSG_DONTWAIT, NULL, 0) = %s \n " ,
( uh_len > DEFAULT_STRLEN ? " ... " : " " ) ,
uh_len , errstr ) ;
2018-04-08 23:48:56 +05:30
}
2017-08-08 22:39:22 +08:00
int
main ( void )
{
skip_if_unavailable ( " /proc/self/fd/ " ) ;
int fd = create_nl_socket ( NETLINK_KOBJECT_UEVENT ) ;
2018-04-08 23:48:56 +05:30
test_nlmsg_type_udev ( fd ) ;
test_nlmsg_type_kernel ( fd ) ;
2017-08-08 22:39:22 +08:00
/* test using data that looks like a zero-length C string */
char * const buf = tail_alloc ( DEFAULT_STRLEN + 1 ) ;
buf [ 0 ] = ' = ' ;
fill_memory_ex ( buf + 1 , DEFAULT_STRLEN , 0 , DEFAULT_STRLEN ) ;
2018-04-04 12:24:19 +00:00
sys_send ( fd , buf + 1 , DEFAULT_STRLEN ) ;
2017-08-08 22:39:22 +08:00
printf ( " sendto(%d, " , fd ) ;
print_quoted_memory ( buf + 1 , DEFAULT_STRLEN ) ;
printf ( " , %u, MSG_DONTWAIT, NULL, 0) = %s \n " ,
2018-04-04 12:24:19 +00:00
DEFAULT_STRLEN , errstr ) ;
2017-08-08 22:39:22 +08:00
2018-04-04 12:24:19 +00:00
sys_send ( fd , buf , DEFAULT_STRLEN + 1 ) ;
2017-08-08 22:39:22 +08:00
printf ( " sendto(%d, " , fd ) ;
print_quoted_memory ( buf , DEFAULT_STRLEN ) ;
printf ( " ..., %u, MSG_DONTWAIT, NULL, 0) = %s \n " ,
2018-04-04 12:24:19 +00:00
DEFAULT_STRLEN + 1 , errstr ) ;
2017-08-08 22:39:22 +08:00
puts ( " +++ exited with 0 +++ " ) ;
return 0 ;
}