193 lines
5.1 KiB
C
193 lines
5.1 KiB
C
/*
|
|
* 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>
|
|
* 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 "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"
|
|
|
|
SYS_FUNC(sysctl)
|
|
{
|
|
struct __sysctl_args info;
|
|
int *name;
|
|
unsigned long size;
|
|
|
|
if (umove_or_printaddr(tcp, tcp->u_arg[0], &info))
|
|
return RVAL_DECODED;
|
|
|
|
size = sizeof(int) * (unsigned long) info.nlen;
|
|
name = (size / sizeof(int) != (unsigned long) info.nlen) ? NULL : malloc(size);
|
|
if (name == NULL ||
|
|
umoven(tcp, (unsigned long) info.name, size, name) < 0) {
|
|
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);
|
|
return RVAL_DECODED;
|
|
}
|
|
|
|
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;
|
|
}
|
|
out:
|
|
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");
|
|
} else if (umove(tcp, ptr_to_kulong(info.oldlenp), &oldlen) >= 0
|
|
&& info.nlen >= 2
|
|
&& ((name[0] == CTL_KERN
|
|
&& (name[1] == KERN_OSRELEASE
|
|
|| name[1] == KERN_OSTYPE
|
|
)))) {
|
|
printpath(tcp, ptr_to_kulong(info.oldval));
|
|
} 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
|
|
printpath(tcp, ptr_to_kulong(info.newval));
|
|
tprintf(", %lu", (unsigned long)info.newlen);
|
|
}
|
|
|
|
free(name);
|
|
return 0;
|
|
}
|