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