2015-12-17 20:56:48 +03:00
/*
* Copyright ( c ) 1999 Ulrich Drepper < drepper @ cygnus . com >
* Copyright ( c ) 2005 Roland McGrath < roland @ redhat . com >
* Copyright ( c ) 2005 - 2015 Dmitry V . Levin < ldv @ altlinux . org >
2018-12-25 02:46:43 +03:00
* Copyright ( c ) 2014 - 2018 The strace developers .
2015-12-17 20:56:48 +03:00
* All rights reserved .
*
2018-12-10 03:00:00 +03:00
* SPDX - License - Identifier : LGPL - 2.1 - or - later
2015-12-17 20:56:48 +03:00
*/
2014-12-03 23:20:52 +03:00
# include "defs.h"
# include <linux/sysctl.h>
# include "xlat/sysctl_root.h"
# include "xlat/sysctl_kern.h"
# include "xlat/sysctl_vm.h"
# include "xlat/sysctl_net.h"
# include "xlat/sysctl_net_core.h"
# include "xlat/sysctl_net_unix.h"
# include "xlat/sysctl_net_ipv4.h"
# include "xlat/sysctl_net_ipv4_route.h"
# include "xlat/sysctl_net_ipv4_conf.h"
# include "xlat/sysctl_net_ipv6.h"
# include "xlat/sysctl_net_ipv6_route.h"
2015-04-07 04:36:50 +03:00
SYS_FUNC ( sysctl )
2014-12-03 23:20:52 +03:00
{
struct __sysctl_args info ;
int * name ;
unsigned long size ;
2015-07-17 02:11:23 +03:00
if ( umove_or_printaddr ( tcp , tcp - > u_arg [ 0 ] , & info ) )
return RVAL_DECODED ;
2014-12-03 23:20:52 +03:00
size = sizeof ( int ) * ( unsigned long ) info . nlen ;
name = ( size / sizeof ( int ) ! = ( unsigned long ) info . nlen ) ? NULL : malloc ( size ) ;
if ( name = = NULL | |
2015-03-21 21:50:53 +03:00
umoven ( tcp , ( unsigned long ) info . name , size , name ) < 0 ) {
2014-12-03 23:20:52 +03:00
free ( name ) ;
if ( entering ( tcp ) )
tprintf ( " {%p, %d, %p, %p, %p, %lu} " ,
info . name , info . nlen , info . oldval ,
info . oldlenp , info . newval , ( unsigned long ) info . newlen ) ;
2015-07-17 02:11:23 +03:00
return RVAL_DECODED ;
2014-12-03 23:20:52 +03:00
}
if ( entering ( tcp ) ) {
unsigned int cnt = 0 , max_cnt ;
tprints ( " {{ " ) ;
if ( info . nlen = = 0 )
goto out ;
printxval ( sysctl_root , name [ 0 ] , " CTL_??? " ) ;
+ + cnt ;
if ( info . nlen = = 1 )
goto out ;
switch ( name [ 0 ] ) {
case CTL_KERN :
tprints ( " , " ) ;
printxval ( sysctl_kern , name [ 1 ] , " KERN_??? " ) ;
+ + cnt ;
break ;
case CTL_VM :
tprints ( " , " ) ;
printxval ( sysctl_vm , name [ 1 ] , " VM_??? " ) ;
+ + cnt ;
break ;
case CTL_NET :
tprints ( " , " ) ;
printxval ( sysctl_net , name [ 1 ] , " NET_??? " ) ;
+ + cnt ;
if ( info . nlen = = 2 )
goto out ;
switch ( name [ 1 ] ) {
case NET_CORE :
tprints ( " , " ) ;
printxval ( sysctl_net_core , name [ 2 ] ,
" NET_CORE_??? " ) ;
break ;
case NET_UNIX :
tprints ( " , " ) ;
printxval ( sysctl_net_unix , name [ 2 ] ,
" NET_UNIX_??? " ) ;
break ;
case NET_IPV4 :
tprints ( " , " ) ;
printxval ( sysctl_net_ipv4 , name [ 2 ] ,
" NET_IPV4_??? " ) ;
if ( info . nlen = = 3 )
goto out ;
switch ( name [ 2 ] ) {
case NET_IPV4_ROUTE :
tprints ( " , " ) ;
printxval ( sysctl_net_ipv4_route ,
name [ 3 ] ,
" NET_IPV4_ROUTE_??? " ) ;
break ;
case NET_IPV4_CONF :
tprints ( " , " ) ;
printxval ( sysctl_net_ipv4_conf ,
name [ 3 ] ,
" NET_IPV4_CONF_??? " ) ;
break ;
default :
goto out ;
}
break ;
case NET_IPV6 :
tprints ( " , " ) ;
printxval ( sysctl_net_ipv6 , name [ 2 ] ,
" NET_IPV6_??? " ) ;
if ( info . nlen = = 3 )
goto out ;
switch ( name [ 2 ] ) {
case NET_IPV6_ROUTE :
tprints ( " , " ) ;
printxval ( sysctl_net_ipv6_route ,
name [ 3 ] ,
" NET_IPV6_ROUTE_??? " ) ;
break ;
default :
goto out ;
}
break ;
default :
goto out ;
}
break ;
default :
goto out ;
}
2017-06-18 01:23:09 +03:00
out :
2014-12-03 23:20:52 +03:00
max_cnt = info . nlen ;
if ( abbrev ( tcp ) & & max_cnt > max_strlen )
max_cnt = max_strlen ;
while ( cnt < max_cnt )
tprintf ( " , %x " , name [ cnt + + ] ) ;
if ( cnt < ( unsigned ) info . nlen )
tprints ( " , ... " ) ;
tprintf ( " }, %d, " , info . nlen ) ;
} else {
size_t oldlen = 0 ;
if ( info . oldval = = NULL ) {
tprints ( " NULL " ) ;
2016-12-26 04:37:21 +03:00
} else if ( umove ( tcp , ptr_to_kulong ( info . oldlenp ) , & oldlen ) > = 0
2014-12-03 23:20:52 +03:00
& & info . nlen > = 2
& & ( ( name [ 0 ] = = CTL_KERN
& & ( name [ 1 ] = = KERN_OSRELEASE
| | name [ 1 ] = = KERN_OSTYPE
) ) ) ) {
2016-12-26 04:37:21 +03:00
printpath ( tcp , ptr_to_kulong ( info . oldval ) ) ;
2014-12-03 23:20:52 +03:00
} else {
tprintf ( " %p " , info . oldval ) ;
}
tprintf ( " , %lu, " , ( unsigned long ) oldlen ) ;
if ( info . newval = = NULL )
tprints ( " NULL " ) ;
else if ( syserror ( tcp ) )
tprintf ( " %p " , info . newval ) ;
else
2016-12-26 04:37:21 +03:00
printpath ( tcp , ptr_to_kulong ( info . newval ) ) ;
2014-12-03 23:20:52 +03:00
tprintf ( " , %lu " , ( unsigned long ) info . newlen ) ;
}
free ( name ) ;
return 0 ;
}