blob: 03d7b1c89906138dbbd54d26e3fe0722fab53fcf [file] [log] [blame]
Dmitry V. Levin172241b2014-12-03 20:20:52 +00001#include "defs.h"
2
3#include <linux/sysctl.h>
4
5#include "xlat/sysctl_root.h"
6#include "xlat/sysctl_kern.h"
7#include "xlat/sysctl_vm.h"
8#include "xlat/sysctl_net.h"
9#include "xlat/sysctl_net_core.h"
10#include "xlat/sysctl_net_unix.h"
11#include "xlat/sysctl_net_ipv4.h"
12#include "xlat/sysctl_net_ipv4_route.h"
13#include "xlat/sysctl_net_ipv4_conf.h"
14#include "xlat/sysctl_net_ipv6.h"
15#include "xlat/sysctl_net_ipv6_route.h"
16
Dmitry V. Levina0bd3742015-04-07 01:36:50 +000017SYS_FUNC(sysctl)
Dmitry V. Levin172241b2014-12-03 20:20:52 +000018{
19 struct __sysctl_args info;
20 int *name;
21 unsigned long size;
22
23 if (umove(tcp, tcp->u_arg[0], &info) < 0)
24 return printargs(tcp);
25
26 size = sizeof(int) * (unsigned long) info.nlen;
27 name = (size / sizeof(int) != (unsigned long) info.nlen) ? NULL : malloc(size);
28 if (name == NULL ||
Denys Vlasenko7e69ed92015-03-21 19:50:53 +010029 umoven(tcp, (unsigned long) info.name, size, name) < 0) {
Dmitry V. Levin172241b2014-12-03 20:20:52 +000030 free(name);
31 if (entering(tcp))
32 tprintf("{%p, %d, %p, %p, %p, %lu}",
33 info.name, info.nlen, info.oldval,
34 info.oldlenp, info.newval, (unsigned long)info.newlen);
35 return 0;
36 }
37
38 if (entering(tcp)) {
39 unsigned int cnt = 0, max_cnt;
40
41 tprints("{{");
42
43 if (info.nlen == 0)
44 goto out;
45 printxval(sysctl_root, name[0], "CTL_???");
46 ++cnt;
47
48 if (info.nlen == 1)
49 goto out;
50 switch (name[0]) {
51 case CTL_KERN:
52 tprints(", ");
53 printxval(sysctl_kern, name[1], "KERN_???");
54 ++cnt;
55 break;
56 case CTL_VM:
57 tprints(", ");
58 printxval(sysctl_vm, name[1], "VM_???");
59 ++cnt;
60 break;
61 case CTL_NET:
62 tprints(", ");
63 printxval(sysctl_net, name[1], "NET_???");
64 ++cnt;
65
66 if (info.nlen == 2)
67 goto out;
68 switch (name[1]) {
69 case NET_CORE:
70 tprints(", ");
71 printxval(sysctl_net_core, name[2],
72 "NET_CORE_???");
73 break;
74 case NET_UNIX:
75 tprints(", ");
76 printxval(sysctl_net_unix, name[2],
77 "NET_UNIX_???");
78 break;
79 case NET_IPV4:
80 tprints(", ");
81 printxval(sysctl_net_ipv4, name[2],
82 "NET_IPV4_???");
83
84 if (info.nlen == 3)
85 goto out;
86 switch (name[2]) {
87 case NET_IPV4_ROUTE:
88 tprints(", ");
89 printxval(sysctl_net_ipv4_route,
90 name[3],
91 "NET_IPV4_ROUTE_???");
92 break;
93 case NET_IPV4_CONF:
94 tprints(", ");
95 printxval(sysctl_net_ipv4_conf,
96 name[3],
97 "NET_IPV4_CONF_???");
98 break;
99 default:
100 goto out;
101 }
102 break;
103 case NET_IPV6:
104 tprints(", ");
105 printxval(sysctl_net_ipv6, name[2],
106 "NET_IPV6_???");
107
108 if (info.nlen == 3)
109 goto out;
110 switch (name[2]) {
111 case NET_IPV6_ROUTE:
112 tprints(", ");
113 printxval(sysctl_net_ipv6_route,
114 name[3],
115 "NET_IPV6_ROUTE_???");
116 break;
117 default:
118 goto out;
119 }
120 break;
121 default:
122 goto out;
123 }
124 break;
125 default:
126 goto out;
127 }
128 out:
129 max_cnt = info.nlen;
130 if (abbrev(tcp) && max_cnt > max_strlen)
131 max_cnt = max_strlen;
132 while (cnt < max_cnt)
133 tprintf(", %x", name[cnt++]);
134 if (cnt < (unsigned) info.nlen)
135 tprints(", ...");
136 tprintf("}, %d, ", info.nlen);
137 } else {
138 size_t oldlen = 0;
139 if (info.oldval == NULL) {
140 tprints("NULL");
141 } else if (umove(tcp, (long)info.oldlenp, &oldlen) >= 0
142 && info.nlen >= 2
143 && ((name[0] == CTL_KERN
144 && (name[1] == KERN_OSRELEASE
145 || name[1] == KERN_OSTYPE
146#ifdef KERN_JAVA_INTERPRETER
147 || name[1] == KERN_JAVA_INTERPRETER
148#endif
149#ifdef KERN_JAVA_APPLETVIEWER
150 || name[1] == KERN_JAVA_APPLETVIEWER
151#endif
152 )))) {
153 printpath(tcp, (size_t)info.oldval);
154 } else {
155 tprintf("%p", info.oldval);
156 }
157 tprintf(", %lu, ", (unsigned long)oldlen);
158 if (info.newval == NULL)
159 tprints("NULL");
160 else if (syserror(tcp))
161 tprintf("%p", info.newval);
162 else
163 printpath(tcp, (size_t)info.newval);
164 tprintf(", %lu", (unsigned long)info.newlen);
165 }
166
167 free(name);
168 return 0;
169}