Text file
src/syscall/mksysctl_openbsd.pl
1 #!/usr/bin/env perl
2
3 # Copyright 2011 The Go Authors. All rights reserved.
4 # Use of this source code is governed by a BSD-style
5 # license that can be found in the LICENSE file.
6
7 #
8 # Parse the header files for OpenBSD and generate a Go usable sysctl MIB.
9 #
10 # Build a MIB with each entry being an array containing the level, type and
11 # a hash that will contain additional entries if the current entry is a node.
12 # We then walk this MIB and create a flattened sysctl name to OID hash.
13 #
14
15 use strict;
16
17 my $debug = 0;
18 my %ctls = ();
19
20 my @headers = qw (
21 sys/sysctl.h
22 sys/socket.h
23 sys/tty.h
24 sys/malloc.h
25 sys/mount.h
26 sys/namei.h
27 sys/sem.h
28 sys/shm.h
29 sys/vmmeter.h
30 uvm/uvm_param.h
31 uvm/uvm_swap_encrypt.h
32 ddb/db_var.h
33 net/if.h
34 net/if_pfsync.h
35 net/pipex.h
36 netinet/in.h
37 netinet/icmp_var.h
38 netinet/igmp_var.h
39 netinet/ip_ah.h
40 netinet/ip_carp.h
41 netinet/ip_divert.h
42 netinet/ip_esp.h
43 netinet/ip_ether.h
44 netinet/ip_gre.h
45 netinet/ip_ipcomp.h
46 netinet/ip_ipip.h
47 netinet/pim_var.h
48 netinet/tcp_var.h
49 netinet/udp_var.h
50 netinet6/in6.h
51 netinet6/ip6_divert.h
52 netinet6/pim6_var.h
53 netinet/icmp6.h
54 netmpls/mpls.h
55 );
56
57 my @ctls = qw (
58 kern
59 vm
60 fs
61 net
62 #debug # Special handling required
63 hw
64 #machdep # Arch specific
65 user
66 ddb
67 #vfs # Special handling required
68 fs.posix
69 kern.forkstat
70 kern.intrcnt
71 kern.malloc
72 kern.nchstats
73 kern.seminfo
74 kern.shminfo
75 kern.timecounter
76 kern.tty
77 kern.watchdog
78 net.bpf
79 net.ifq
80 net.inet
81 net.inet.ah
82 net.inet.carp
83 net.inet.divert
84 net.inet.esp
85 net.inet.etherip
86 net.inet.gre
87 net.inet.icmp
88 net.inet.igmp
89 net.inet.ip
90 net.inet.ip.ifq
91 net.inet.ipcomp
92 net.inet.ipip
93 net.inet.mobileip
94 net.inet.pfsync
95 net.inet.pim
96 net.inet.tcp
97 net.inet.udp
98 net.inet6
99 net.inet6.divert
100 net.inet6.ip6
101 net.inet6.icmp6
102 net.inet6.pim6
103 net.inet6.tcp6
104 net.inet6.udp6
105 net.mpls
106 net.mpls.ifq
107 net.key
108 net.pflow
109 net.pfsync
110 net.pipex
111 net.rt
112 vm.swapencrypt
113 #vfsgenctl # Special handling required
114 );
115
116 # Node name "fixups"
117 my %ctl_map = (
118 "ipproto" => "net.inet",
119 "net.inet.ipproto" => "net.inet",
120 "net.inet6.ipv6proto" => "net.inet6",
121 "net.inet6.ipv6" => "net.inet6.ip6",
122 "net.inet.icmpv6" => "net.inet6.icmp6",
123 "net.inet6.divert6" => "net.inet6.divert",
124 "net.inet6.tcp6" => "net.inet.tcp",
125 "net.inet6.udp6" => "net.inet.udp",
126 "mpls" => "net.mpls",
127 "swpenc" => "vm.swapencrypt"
128 );
129
130 # Node mappings
131 my %node_map = (
132 "net.inet.ip.ifq" => "net.ifq",
133 "net.inet.pfsync" => "net.pfsync",
134 "net.mpls.ifq" => "net.ifq"
135 );
136
137 my $ctlname;
138 my %mib = ();
139 my %sysctl = ();
140 my $node;
141
142 sub debug() {
143 print STDERR "$_[0]\n" if $debug;
144 }
145
146 # Walk the MIB and build a sysctl name to OID mapping.
147 sub build_sysctl() {
148 my ($node, $name, $oid) = @_;
149 my %node = %{$node};
150 my @oid = @{$oid};
151
152 foreach my $key (sort keys %node) {
153 my @node = @{$node{$key}};
154 my $nodename = $name.($name ne '' ? '.' : '').$key;
155 my @nodeoid = (@oid, $node[0]);
156 if ($node[1] eq 'CTLTYPE_NODE') {
157 if (exists $node_map{$nodename}) {
158 $node = \%mib;
159 $ctlname = $node_map{$nodename};
160 foreach my $part (split /\./, $ctlname) {
161 $node = \%{@{$$node{$part}}[2]};
162 }
163 } else {
164 $node = $node[2];
165 }
166 &build_sysctl($node, $nodename, \@nodeoid);
167 } elsif ($node[1] ne '') {
168 $sysctl{$nodename} = \@nodeoid;
169 }
170 }
171 }
172
173 foreach my $ctl (@ctls) {
174 $ctls{$ctl} = $ctl;
175 }
176
177 # Build MIB
178 foreach my $header (@headers) {
179 &debug("Processing $header...");
180 open HEADER, "/usr/include/$header" ||
181 print STDERR "Failed to open $header\n";
182 while (<HEADER>) {
183 if ($_ =~ /^#define\s+(CTL_NAMES)\s+{/ ||
184 $_ =~ /^#define\s+(CTL_(.*)_NAMES)\s+{/ ||
185 $_ =~ /^#define\s+((.*)CTL_NAMES)\s+{/) {
186 if ($1 eq 'CTL_NAMES') {
187 # Top level.
188 $node = \%mib;
189 } else {
190 # Node.
191 my $nodename = lc($2);
192 if ($header =~ /^netinet\//) {
193 $ctlname = "net.inet.$nodename";
194 } elsif ($header =~ /^netinet6\//) {
195 $ctlname = "net.inet6.$nodename";
196 } elsif ($header =~ /^net\//) {
197 $ctlname = "net.$nodename";
198 } else {
199 $ctlname = "$nodename";
200 $ctlname =~ s/^(fs|net|kern)_/$1\./;
201 }
202 if (exists $ctl_map{$ctlname}) {
203 $ctlname = $ctl_map{$ctlname};
204 }
205 if (not exists $ctls{$ctlname}) {
206 &debug("Ignoring $ctlname...");
207 next;
208 }
209
210 # Walk down from the top of the MIB.
211 $node = \%mib;
212 foreach my $part (split /\./, $ctlname) {
213 if (not exists $$node{$part}) {
214 &debug("Missing node $part");
215 $$node{$part} = [ 0, '', {} ];
216 }
217 $node = \%{@{$$node{$part}}[2]};
218 }
219 }
220
221 # Populate current node with entries.
222 my $i = -1;
223 while (defined($_) && $_ !~ /^}/) {
224 $_ = <HEADER>;
225 $i++ if $_ =~ /{.*}/;
226 next if $_ !~ /{\s+"(\w+)",\s+(CTLTYPE_[A-Z]+)\s+}/;
227 $$node{$1} = [ $i, $2, {} ];
228 }
229 }
230 }
231 close HEADER;
232 }
233
234 &build_sysctl(\%mib, "", []);
235
236 print <<EOF;
237 // mksysctl_openbsd.pl
238 // Code generated by the command above; DO NOT EDIT.
239
240 package syscall;
241
242 type mibentry struct {
243 ctlname string
244 ctloid []_C_int
245 }
246
247 var sysctlMib = []mibentry {
248 EOF
249
250 foreach my $name (sort keys %sysctl) {
251 my @oid = @{$sysctl{$name}};
252 print "\t{ \"$name\", []_C_int{ ", join(', ', @oid), " } }, \n";
253 }
254
255 print <<EOF;
256 }
257 EOF
258
View as plain text