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