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